... setTimeout に固執せずにこれを達成するにはどうすればよいですか?
長時間実行される複雑なコードをブラウザーに返したくない場合は、Web ワーカーを使用できます。このコードは DOM を直接変更することはできませんが、メッセージをメイン スクリプトにポストして、メイン スクリプトに何を変更するかを伝えることができます。
Web ワーカーをサポートしていないブラウザーでは、基本的に (setTimeout
およびそのいとこ) を返すしかありません。
ウェブ上でさまざまなウェブワーカーの例を見つけることができますが、価値があるのは、ここで別の回答のために行ったものです。これは、多数にカウントする進行状況を示しています。しかし、概念は同じです。長期実行スクリプトは、メインの JavaScript スレッドとは別に実行され、更新を 経由で投稿しますpostMessage
。
主なドキュメントとスクリプト:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Progress</title>
<style type="text/css">
body, html {
height: 100%;
}
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="progress"><em>(Click to start)</em></div>
<script>
(function() {
var div = document.getElementById("progress");
var counter = new Worker("counter.js");
div.addEventListener("click", run);
counter.addEventListener("message", function(event) {
div.innerHTML = "Counter so far: " + event.data.counter;
});
function run() {
div.removeEventListener("click", run);
counter.postMessage({ max: 10000000 });
}
})();
</script>
</body>
</html>
counter.js
web-worker スクリプト (これらは常に別のファイルです):
self.addEventListener("message", function(event) {
var max;
var counter;
max = event.data && event.data.max || 100000;
for (counter = 0; counter < max; ++counter) {
if (counter % 1000 === 0) {
self.postMessage({counter: counter});
}
}
self.postMessage({counter: counter});
});