awaitの使用例
まずdeveloper.mozillaの説明を引用しますと
await 演算子は、async function によって Promise が返されるのを待機するために使用します。
下の例ではawait processA()でprocessAの解決を待ったあとに以下の処理が走ります。
processA()の実行終了を待ってからprocessB()の実行をしたい場合に有効です。
const processA = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processA') }, 1000) }) } const processB = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processB') }, 500) }) } async function asyncCall() { console.log(await processA()) console.log(await processB()) } asyncCall() // expect: // done processA // done processB
thenの使用例
developer.mozillaの説明を引用しますと
then() メソッドは Promise を返します。最大2つの引数、 Promise が成功した場合と失敗した場合のコールバック関数を取ります
awaitとの大きな違いは、あくまでPromiseの解決を待つだけで、その後の処理を止めたりはしません。
そのため、以下の例では先に終了するBが先に出力されます。
const processA = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processA') }, 1000) }) } const processB = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processB') }, 500) }) } function callThen() { processA().then(v => { (console.log(v)) }) processB().then(v => { (console.log(v)) }) } callThen() // expect // done processB // done processA
awaitを使わないほうが良い場合
awaitはPromiseが帰ってくるまで処理を止めるので、上の例ではProcessAを1秒待ったあとにProcessBを実行します。
ただ、ProcessAを待たなくても良い場合は、無駄に実行を止めていることになってしまっています。
実務の例では、APIを取得するときに、AのAPIの終了を待たなくても良いのにawait Aとして、次にBのAPIをawait Bで実行しているなどです。
並列処理ができるPromise.all()について
順番に実行する必要がないため並列でPromiseを処理したいけれど、何度もthenを書きたくない場合にPromise.allが使えます。
これは引数のPromiseが並列で実行されて、全て解決されるまで待ちます。またあるPromiseが拒否された場合、その拒否した Promise の値で拒否されます。
Promise.all() - JavaScript | MDN
const processA = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processA') }, 1000) }) } const processB = () => { return new Promise(resolve => { setTimeout(() => { resolve('done processB') }, 500) }) } const start = performance.now() async function callPromiseAll() { return await Promise.all([processA(), processB()]) } callPromiseAll().then(v => { console.log(v) const end = performance.now() console.log(end - start) // 単位はミリ秒 }) // expected // > Array ["done processA", "done processB"] // 入れたPromiseの順番で結果が配列で格納されています // > 1002.8999999910593 // setTimeoutの合計は1.5秒ですが、1秒と少しのため並列で実行されていると分かります