2017-10-24 9 views
3

以下のコードには、outer関数とinner関数があります。 outerawaitinnerとなっています。 innerは、タイムアウト後に実行されるPromiseを返します。入れ子プロミスが実行されるのを待つ間に非同期関数が返されない

const outer = async() => { 
    let counter = 0; 
    const inner = async() => { 
     console.log('inner'); 
     return new Promise((fulfill, reject) => { 
      if (++counter === 3) { 
       console.log('fulfill'); 
       fulfill(); 
       return; 
      } 
      setTimeout(() => inner(), 1000); 
     }); 
    }; 
    return await inner(); 
}; 
outer().then(() => console.log('outer done')); 

outerはいえ完了したことがない:私はこのPromiseが満たされた後outer関数は右を返すことを期待しています。次のコードouter完了で

inner 
inner 
inner 
fulfill 

:なしouter done出力が存在しないことに注意してください。それはPromise自身を返し、inner機能はそれを満たし:

const outer = async() => { 
    return new Promise((fulfill, reject) => { 
     let counter = 0; 
     const inner = async() => { 
      console.log('inner'); 
      if (++counter === 3) { 
       console.log('fulfill'); 
       fulfill(); 
       return; 
      } 
      setTimeout(() => inner(), 1000); 
     }; 
     inner().catch(err => reject(err)); 
    }); 
}; 
outer().then(() => console.log('outer done')); 

は出力:

inner 
inner 
inner 
fulfill 
outer done 

私は行動が両方のこれらの場合に類似しているべきであると考えました。誰でもその違いを見て説明することができますか?

答えて

4

innerfullfill関数を呼び出したことはありません。あなたは新しい約束を作りました、そして、あなたはそれが解決されたという最後の約束を伝えました。この部分、すなわちinnerへの最初の呼び出しで

{ 
    if (++counter === 3) { 
     console.log('fulfill'); 
     fulfill(); 
     return; 
    } 
    setTimeout(() => inner(), 1000); 
} 

私たちはあなたの非同期タスクを見てみましょう

return await inner(); 

counter全体ifブロックを意味0であります実行されません。コードの残りの部分では、それは決してfulfillという関数を呼び出さなかったので、約束は決して解決されませんでした。

このコード(またはこのコードスタイル)が本番コードベースに存在する場合は、私はそのコードを書き直す必要があります。本当にすぐそれを修正する

あなたはおそらくこれを行うことができます。

setTimeout(() => inner().then(() => fulfill()), 1000); 

Demo

+0

をどのような場合には、 'fulfill'ログの存在を説明していますか?コードがその点に達することが証明されます。 –

+0

@YuryFedorovあなたは最後の約束を果たしましたが、あなたが* 4つの新しい約束を作成したことを忘れないでください。ログは実際にそれが到達していないことを証明しています。なぜなら、1ではなく4つの線があるからです。 –

+0

ああ、今、私はそれを見ています。いいね、ありがとう –

関連する問題