関数を非同期で実行したい場合、最初に思いつくメソッドは間違いなく setTimeout
例: setTimeout(function( /* 1 秒後に何かを実行 */){},1000}
関数をできるだけ早く非同期で実行したい場合はどうすればよいでしょうか?
それは次のようになります:
setTimeout(function( /* 尽快做点什么 */){},0}
残念ながら、setTimeout のネストによる UI スレッドのブロックの可能性を回避するために、ブラウザーは setTimeout の最小実行時間間隔を設定します。最小実行時間間隔はブラウザーによって異なります。 Chrome でテストした場合の setTimeout 0 の実際の実行時間間隔は約 12 ミリ秒です。 <br /> <br /> では、関数をできるだけ早く非同期で実行したい場合、それを高速化する方法はあるのでしょうか?
まずブラウザ側を見て、一般的に使用される非同期実行メソッドが何であるかを見てみましょう
setImmediate: このメソッドは setTimeout 0 よりも高速な非同期実行を実現し、実行時間は 0 ミリ秒に近くなりますが、IE/ノードでのみサポートされます。
requestAnimationFrame: このメソッドは、アニメーション ループを実行するときによく使用されます。このメソッドは、ブラウザーが UI を更新するときにのみ実行されます。そのため、requestAnimationFrame は一般に setTimeout 0 よりも遅くなります。
非同期関数の使用に加えて、非同期呼び出しを実装する方法がいくつかあります
メッセージで使用します: <br /> onmessage メソッドは、iframe と通信するときによく使用されますが、同じウィンドウがそれ自体に Message を投稿するとどうなるでしょうか。実際、これは関数を非同期で実行するのと同じです<br /> 例:
var doSth = function(){} window.addEventListener("message", doSth, true); window.postMessage("", "*");
<コード><br />
さらに、スクリプト タグを使用して関数の非同期実行を実装することもできます。例: <br />
<コード><br />
var newScript = document.createElement("script"); newScript.onreadystatechange = doSth; document.documentElement.appendChild(newScript);
<コード><br />
<br />
ドキュメントにスクリプトを追加すると、onreadystatechange も実行されますが、このメソッドは IE ブラウザーでのみ使用できます。
それでは、これらの方法の中でどれが最も速いのでしょうか?
テストしました、
クロムの下:
setImmediate: 使用できません。 <br /> setTimeout 0:12ms<br /> メッセージ時: 6ms<br /> onreadystatechange: サポートされていません
Chrome では、onmessage は setTimeout 0 よりも高速です。
Firefox の下:
setImmediate: 使用できません。 <br /> setTimeout 0:7ms<br /> メッセージ時: 7ms<br /> onreadystatechange: サポートされていません
Firefox では、onmessage と setTimeout 0 は同等に高速です。
IE9:
setImmediate: 使用できません。 <br /> setTimeout 0:11ms<br /> メッセージ時: 7ms 10ms<br /> onreadystatechange: 2ms
IE9 では、onreadystatechange の時間は他の 2 つよりもはるかに高速です。
一般に、setImmediate
var setZeroTimeout = (function(){
if(window.setImmediate){
//IE10+版本,使用原生setImmediate
return window.setImmediate;
}
else if("onreadystatechange" in document.createElement("script")){
return function(){/* 使用onreadystatechange的版本 */}
}
else if(window.postMessage){
return function(){/* 使用onmessage的异步执行版本 */}
}
else {
return window.setTimeout;
}
})();