次のPromise
があるとします:
_function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
_
doSomeWork()
はどの時点で呼び出されますか? Promise
が作成された直後ですか、それとも作成されていますか?そうでない場合、Promise
の本体が実行されることを確認するために明示的に行う必要がある追加の何かがありますか?
すぐに、はい、仕様により。
MDN から:
Executor関数はPromise実装によって直ちに実行され、resolveおよびreject関数を渡します(Promiseコンストラクターが作成されたオブジェクトを返す前にexecutorが呼び出されます)
これはECMAScript仕様にあります(もちろん読みにくい...): http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor
この保証は、たとえば、いくつかのプロミスを準備しているときにall
またはrace
に渡す場合、またはエグゼキューターに同期的な副作用がある場合に重要です。
はい、Promise
を作成すると、最初のパラメーターがすぐに実行されます。
一般に、現在の実装と同じように、promise
を実際に使用することはありません。
タイムアウトを使用して実装するか、ajaxコールバックの一部として解決関数を呼び出します
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
setTimeout
メソッドは、イベントキューが解放された次の瞬間に関数を呼び出します
下から、非同期ではなく同期コードを本体に入れるだけで、本体がすぐに実行されることがわかります。
_function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();console.log("b");
_
結果は、promise本体がすぐに実行されることを示しています(「b」が出力される前)。
_a
b
_
Promiseの結果は保持され、たとえば「then」呼び出しにリリースされます。
_doSomethingAsynchronous().then(function(pr){console.log("c:"+pr);});console.log("b");
_
結果:
_a
b
c:promise result
_
約束が満たされ、「then」が呼び出される前の不確定な遅延を除いて、ボディの非同期コードも同様に処理されます(ポイント「c」)。したがって、doSomethingAsynchronous()
が返るとすぐに 'a'と 'b'が出力されますが、約束が満たされた( 'resolve'が呼び出された)場合にのみ 'c'が表示されます。
「then」への呼び出しが追加されると、表面上は奇妙に見えますが、すべてが同期している場合でも「c」の前に「b」が出力されます。確かに「a」が印刷され、次に「c」、最後に「b」が印刷されますか? 「a」、「b」、「c」がこの順序で出力される理由は、本体のコードが非同期か同期かに関係なく、「then」メソッドがPromiseによって常に非同期に呼び出されるためです。
私の考えでは、「resolve」が呼び出されると、PromiseのsetTimeout(function(){then(pr);},0);
のようなものによって呼び出される 'then'メソッドを想像します。つまり「then」に渡された関数が実行される前に、現在の実行パスが完了する必要があります。
Promise仕様から、なぜこれを行うのかは明らかではありません。私の推測では、すべてのPromises
呼び出しを開始する前に複数のthen
をスタック/チェーンできるようにするために、「then」が呼び出されるとき(常に現在の実行スレッドが終了した後)に一貫した動作を保証します連続して。
EcmaScript仕様から http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor
Executor関数はPromise実装によって直ちに実行され、resolveおよびreject関数を渡します(Promiseコンストラクターが作成されたオブジェクトを返す前にexecutorが呼び出されます)
次のコードを検討してください。
var executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if(asynkTaskCompleted){
resolve("Pass resolved Value here");
}else{
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction);
上記のコードを実行すると、約束を宣言するとすぐにexecutorFunctionが自動的に呼び出され、明示的に呼び出す必要はありません。