初めに
今回はasync
とawait
キーワードについてまとめていきたいと思います。
参考文章はこちらです。
Async/await - javascript.info
async
/await
async
:関数が解決(resolve)されたPromise
を返すことが約束される。
await
:async
関数の中で、指定のPromise
が完了(settled)状態になるまで待つ。async function
の中のみ動作する。
await
await
の動きを見ていきたいと思います。
async function fn() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('done!'), 1000)
})
let result = await promise
console.log('before result')
console.log(result)
console.log('after result')
}
fn()
console.log('after fn')
// after fn
// before result
// done!
// after result
async
関数fn
を呼び出したあとconsole.log('after fn')
が実行し、fn
に戻ってawait
が変数promise
のsetTimeout()
がresolve()
を返すまで待ち、最後に残りの部分が同期に実行していきます。
await
とsetTimeout()
、resolve()
併用すれば結果の出す時間が計測器でちゃんと作動し、await
で必ず結果を得てから後の処理を継続していく。async
もawait
もとても便利でわかりやすく使うキーワードだと思います。
しかしテストの中ちょっと気になるところまた出てきましたので、
例えば、await
をつけたPromise
はPromise
オブジェクトとして使えるでしょうか。
async function test() {
let promise = await new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 3000)
})
promise.then((result) => {
console.log(result)
})
}
test()
// UnhandledPromiseRejectionWarning: TypeError: promise.then is not a function
実行すると未処理エラーが出てました。あれと思って、
async function test() {
let promise = await new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 3000)
})
// promise.then((result) => {
// console.log(result)
// })
console.log(typeof promise) // string
console.log(promise instanceof Promise) // false
console.log(promise.toString()) // 123
}
test()
await
を外すとこうなるんですが、
console.log(typeof promise) // object
console.log(promise instanceof Promise) // true
console.log(promise.toString()) // [object Promise]
そしてPromise.resolve()
を使って、then
が正常に動作してくれました。
Promise.resolve(promise)
.then((result) => {
console.log(result) // 123
})
もちろんasync
なら、関数test
が返された結果をPromise
でラップし、then
でその結果を受け取り、進んでいきます。
async function test() {
let promise = await new Promise((resolve, reject) => {
setTimeout(() => resolve('123'), 3000)
})
return promise
}
test()
.then(result => console.log(result)) // 123
下はasync
をつけた関数の検定です。
console.log(test().toString()) // [object Promise]
console.log(test() instanceof Promise) //true