私がやろうとしていることは、CPUを多用するスクリプトを実行する前に、単純なdivを「Processing ...」と更新して(実行に3〜12秒かかり、AJAXがない)、divを更新して「Finished! 」それが終わったら。
私が見ているのは、divが「Processing ...」で更新されないことです。そのコマンドの直後にブレークポイントを設定すると、divテキストが更新されるため、構文が正しいことがわかります。 IE9、FF6、Chrome13で同じ動作。
JQueryをバイパスして基本的な生のJavascriptを使用している場合でも、同じ問題が発生します。
これは簡単な答えがあると思います。ただし、jQuery .html()および.text()にはコールバックフックがないため、これはオプションではありません。また、アニメーション化されていないため、操作する.queueはありません。
5秒の高CPU機能を備えたjQuery実装とJavascript実装の両方を示す以下で準備したサンプルコードを使用して、これを自分でテストできます。コードは簡単に追跡できます。ボタンまたはリンクをクリックしても、「Processing ...」が表示されない
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script>
<script type="text/javascript">
function addSecs(d, s) {return new Date(d.valueOf()+s*1000);}
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished JS';
}
$(function() {
$('button').click(function(){
$('div').text('Processing JQ...');
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
$('div').text('Finished JQ');
});
});
</script>
</head>
<body>
<div id="msg">Not Started</div>
<button>jQuery</button>
<a href="#" onclick="doRun()">javascript</a>
</body>
</html>
これを処理に設定してから、setTimeoutを実行して、divが更新されるまでCPUを集中的に使用するタスクが実行されないようにします。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script>
<script>
function addSecs(d, s) {return new Date(d.valueOf()+s*1000);}
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
setTimeout(function(){
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished Processing';
},10);
}
$(function() {
$('button').click(doRun);
});
</script>
</head>
<body>
<div id="msg">Not Started</div>
<button>jQuery</button>
<a href="#" onclick="doRun()">javascript</a>
</body>
</html>
必要に応じてsetTimeout遅延を変更できます。遅いマシン/ブラウザでは、より大きくする必要がある場合があります。
編集:
アラートまたは確認ダイアログを使用して、ページの更新を許可することもできます。
document.getElementById('msg').innerHTML = 'Processing JS...';
if ( confirm( "This task may take several seconds. Do you wish to continue?" ) ) {
// run code here
}
5秒間実行され、その間Webブラウザーをフリーズするループがあります。 Webブラウザーはフリーズされているため、レンダリングを実行できません。ループの代わりにsetTimeout()
を使用する必要がありますが、ループは、時間がかかるCPU集中型の関数の代わりにすぎないと思いますか? setTimeoutを使用して、関数を実行する前にブラウザーにレンダリングする機会を与えることができます。
jQuery:
$(function() {
$('button').click(function(){
(function(cont){
$('div').text('Processing JQ...');
start = new Date();
end = addSecs(start,5);
setTimeout(cont, 1);
})(function(){
do {start = new Date();} while (end-start > 0);
$('div').text('Finished JQ');
})
});
});
バニラJS:
document.getElementsByTagName('a')[0].onclick = function(){
doRun(function(){
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished JS';
});
return false;
};
function doRun(cont){
document.getElementById('msg').innerHTML = 'Processing JS...';
start = new Date();
end = addSecs(start,5);
setTimeout(cont, 1);
}
また、常にvarキーワードを使用してすべての変数を宣言し、それらをグローバルスコープに公開しないようにしてください。ここにJSFiddleがあります:
私はjQueryがDOMを操作するのを待って、変更を把握する必要がありました(フォームフィールドをフォームに複数回ロードしてから送信する)。 DOMが大きくなり、挿入に時間がかかりました。 ajaxを使用して変更を保存し、ユーザーが中断したところから続行できるようにする必要があります。
これはNOT WORKを意図したとおりにしました:
_jQuery('.parentEl').prepend('<p>newContent</p>');
doSave(); // wrapping it into timeout was to short as well sometimes
_
.prepend()
のようなjQuery関数は、完了時にのみチェーンを継続するため、以下はトリックを行うのようです。
_jQuery('.parentEl').prepend('<p>newContent</p>').queue(function() {
doSave();
});
_
2019以降、setTimeoutを使用して競合状態を作成する代わりに、フレームをスキップするためにdoublerequesAnimationFrame
を使用しています。
....
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
requestAnimationFrame(() =>
requestAnimationFrame(function(){
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished Processing';
}))
}
...