はじめに
javascriptはシングルスレッド、ブラウザはマルチスレッド、すべての非同期ソリューションは最終的にコールバックです。
プロミスの基本的な使い方と本質
let p1 = new Promise((resolve, reject) => {
let arr = [1,2,3,4,5];
let arr1 = arr.filter(item => item > 3);
setTimeout(() => {
resolve(arr1);
}, 1000)
})
p1.then(res => {
console.log(res);
},err => {
console.log(err);
})
つまり、pending->resolve(満たされた状態)か、pending->rejected(拒否された状態)のどちらかしか変化しません;
このメソッドは、2つの変化した状態に対応する2つのパラメーターと
その後チェーンコール
const p1 = new Promise((resolve, reject) => {
let arr = [1,2,3,4,5];
let arr1 = arr.filter(item => item > 3);
setTimeout(() => {
resolve(arr1);
}, 1000)
})
p1
.then(res => {
console.log(res)
//thenコールバックはプロミスを返すことができる。
return new Promise((resolve, reject) => {
let arr2 = [1,2,3];
setTimeout(() => {
resolve(arr2)
}, 1000);
})
})
.then(res => {
console.log(res)
//thenコールバックで値を返すこともできる。
return 1
})
.then(res => {
console.log(res)
})
//
//[4,5];
//[1,2,3];
//1
async/awaitの基本的な使い方
互いに依存し合う複数のリクエストを扱う場合、promiseのthenメソッドは面倒で、async/awaitは軽量です。
使い方:
- 関数の前に async を追加すると、関数の実行後に自動的に Promise オブジェクトが返されます。
//eg1
async function Person() {
}
let result = Person()
console.log(result);
//Personメソッドは戻り値を持たないが、結果はPromiseオブジェクトとして出力される。
//Promise {<resolved>: undefined}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: undefined
//eg2:
async function Person() {
return 2
}
let result = Person()
console.log(result);// Promise {<resolved>: 2}
//Promise {<resolved>: 2}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: 2
- aitは単独ではなく、非同期関数の内部で使用する必要があります。
async function Person() {
let result = await Promise.resolve('success')
console.log(result)
}
Person()
- awaitはPromiseオブジェクトに従う必要があり、そうでなければ意味がありません。
function ret() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
})
})
}
async function test() {
let result = await ret() //fnはPromiseオブジェクトを返すので
console.log(result) //ここでは、promiseが成功した後に渡されるコードをタイプアウトする。'success'
}
test()
非同期/待機エラー処理
エラー処理に関しては、awaitはPromiseの成功状態をパラメータとして受け取るので、エラーをキャッチするためにtry catchが必要です。
function ret (num){
return new Promise((resolve, reject) => {
setTimeout(() => {
if (num >= 100) {
resolve('success')
} else {
reject('failed')
}
}, 1000)
})
}
async function test() {
let result = await ret(222)
return result //awaitはPromiseの成功ステータスを受け付けるので、失敗するとcatchに飛ぶ。
}
test().then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
async/await
非同期関数の中でawaitを使うと、awaitの中のコードは同期的で、awaitの後のPrimiseコードが実行し終わるのを待つだけで、次の行に進むことができます。
function fn(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${name}成功`)
}, 1000)
})
}
async function test() {
let p1 = await fn(' ')
let p2 = await fn('小明')
let p3 = await fn(' ')
return [p1, p2, p3]
}
test().then(result => {
console.log(result)
}).catch(result => {
console.log(result)
})
Demo
約束
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
request(500).then(result => {
return request(result + 1000)
}).then(result => {
return request(result + 1000)
}).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
async/awaitへの変換
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
async function getResult() {
let p1 = await request(500)
let p2 = await request(p1 + 1000)
let p3 = await request(p2 + 1000)
return p3
}
getResult().then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})





