開発した長い JavaScript 処理中に UI をフリーズさせないことが主な関心事である場合は、ループ本体を順次ステップにリファクタリングして、各ステップが を使用して次のステップを呼び出すようにすることができますwindow.setTimeout
。この手法により、(単一の) スレッドが各インタラクション間で UI イベントを処理できるようになります。
var pr = function(x) {console.log(x)};
var COUNT=3;
// original regular javascript loop
for(var i=0; i<COUNT; i++) {
var msg = "current index is (" + i + ")";
pr(msg);
}
// step-by-step sequential calls
var body = function(i) {
var msg = "non-blocking for: index is (" + i + ")";
pr(msg);
}
nonBlockingFor(body, 4);
この関数nonBlockingFor
は、2 番目の引数として渡された回数だけ、最初の引数を (関数として) 呼び出します。その定義は次のとおりです。
// function constructor
var nonBlockingFor = (function() {
function _run(context) {
if(context.idx > context.max) return;
context.fnc(context.idx++);
window.setTimeout((function(){ _run(context)}), 1);
}
return (function _start(ufn, uqt, runId) {
_run({idx: 0, max: uqt -1, fnc: ufn || (function(){}), runId: runId});
});
})();
これは非常に単純化された関数であり、他のマルチスレッド関連の問題を処理するように改善できることに注意してください。つまり、スレッドの終了 (結合) を待機します。このコードがお役に立てば幸いです。問題に対するこのアプローチが気に入ったら、私に知らせてください。よろしければ、私の提案を改善するために時間を費やすことができます。