promiseの唯一の問題は、IEがそれらをサポートしていないことです。Edgeにはありますが、IE 10と11はたくさんあります:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise(下部の互換性)
したがって、JavaScriptはシングルスレッドです。非同期呼び出しを行わない場合は、予測どおりに動作します。メインのJavaScriptスレッドは、次の関数を実行する前に、コード内に出現する順に1つの関数を完全に実行します。同期関数の保証順序は簡単です。各関数は、呼び出された順序で完全に実行されます。
同期関数は、アトミックな作業単位と考えてください。メインのJavaScriptスレッドは、ステートメントがコードに出現する順序で完全に実行します。
ただし、次の状況のように、非同期呼び出しをスローします。
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
これはあなたが望むことをしません。関数1、関数2、関数3を瞬時に実行します。divのロードがフラッシュして消えますが、ajaxの呼び出しは、makeAjaxCall()
戻ってきてもほぼ完了していません。複雑さは、makeAjaxCall()
その作業をチャンクに分割し、メインのJavaScriptスレッドのスピンごとに少しずつ進めることです。これは非同期に動作しています。しかし、同じメインスレッドが1回のスピン/実行中に、同期部分をすばやく予測どおりに実行しました。
それで、私がそれを処理した方法:私が言ったように、関数は仕事の原子単位です。関数1と関数2のコードを結合しました-非同期呼び出しの前に関数1のコードを関数2に入れました。私は関数1を取り除きました。非同期呼び出しまでのすべてが、順番に予測どおりに実行されます。
次に、非同期呼び出しが完了したら、メインJavaScriptスレッドを数回スピンした後、関数3を呼び出します。これにより、順序が保証されます。たとえば、ajaxでは、onreadystatechangeイベントハンドラーが複数回呼び出されます。完了したと報告されたら、必要な最終関数を呼び出します。
面倒だと思う。コードを対称にすること、関数が1つのこと(またはそれに近いこと)を行うこと、およびajax呼び出しが表示を担当する(呼び出し元への依存関係を作成する)ことは好きではありません。ただし、同期関数に組み込まれた非同期呼び出しでは、実行順序を保証するために妥協する必要があります。また、IE 10をコーディングする必要があるため、約束はありません。
要約:同期呼び出しの場合、順序を保証することは簡単です。各関数は、呼び出された順序で完全に実行されます。非同期呼び出しのある関数の場合、順序を保証する唯一の方法は、非同期呼び出しがいつ完了するかを監視し、その状態が検出されたときに3番目の関数を呼び出すことです。
JavaScriptスレッドの説明については、https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23およびhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/を参照してください。 EventLoop
また、この主題に関する同様の非常に評価の高い別の質問:3つの関数を順番に実行するには、どのように呼び出す必要がありますか?
firstFunction
それは正確にそれを非同期にしますか?どちらにしても、約束について確認する