web-dev-qa-db-ja.com

javascript ES6 Promisesが解決後も実行を続けるのはなぜですか?

私が理解しているように、promiseはresolve()またはreject()できるものですが、resolveまたはrejectが呼び出された後、promiseのコードが実行し続けることを知って驚きました。

私は、すべての即時関数実行を停止するexitまたはreturnの非同期対応バージョンであることを解決または拒否することを検討しました。

誰かが、次の例が解決呼び出し後にconsole.logを表示することがある理由の背後にある考えを説明できますか?

var call = function() {
    return new Promise(function(resolve, reject) {
        resolve();
        console.log("Doing more stuff, should not be visible after a resolve!");
    });
};

call().then(function() {
    console.log("resolved");
});

jsbin

73

JavaScriptの概念は "run to completion" です。エラーがスローされない限り、関数はreturnステートメントまたはその終わりに達するまで実行されます。関数の外部にある他のコードはこれに干渉できません(再度エラーがスローされない限り)。

resolve()で初期化関数を終了する場合は、returnを先頭に追加する必要があります。

return new Promise(function(resolve, reject) {
    return resolve();
    console.log("Not doing more stuff after a return statement");
});
116
Felix Kling

Promiseをresolveするときに呼び出されるコールバックは、非同期で呼び出されるために仕様でまだ必要です。これは、同期アクションと非同期アクションが混在するプロミスを使用する場合の一貫した動作を保証するためです。

したがって、resolveを呼び出すと、コールバックはqueuedになり、resolve()呼び出しに続くコードで関数の実行が直ちに続行されます。

JSイベントループに制御が戻ると、コールバックをキューから削除して実際に呼び出すことができます。

18
Alnitak