変数のコピーが 2 つ存在するわけではありません。Web ブラウザーの Javascript はシングル スレッドです (新しい Web ワーカーを使用しない限り)。したがって、無名関数は実行する機会がありません。これWait
は、インタープリターが拘束されているためです。
ブラウザーベースの Javascript でビジー待機関数を使用することはできません。他には何も起こりません (そして、他のほとんどの環境では、たとえ可能であっても、それは悪い考えです)。代わりにコールバックを使用する必要があります。これをミニマリストにリワークすると次のようになります。
var interval_id;
var countdowntimer = 0;
function Wait(wait_interval, callback) {
countdowntimer = wait_interval;
interval_id = setInterval(function() {
if (--countdowntimer <=0) {
clearInterval(interval_id);
interval_id = 0;
callback();
}
}, 1000);
}
// Wait a bit: 5 secs
Wait(5, function() {
alert("Done waiting");
});
// Any code here happens immediately, it doesn't wait for the callback
あなたのフォローアップに答える編集:
しかし、この単一スレッドの処理のどの時点で、setInterval を使用したいわゆる非同期呼び出しが実際に行われるのでしょうか? 関数呼び出しの間だけですか?そうではありません。実行に時間がかかる関数はどうでしょうか。
そのため、関数が長時間実行されないようにすることが重要です。(技術的には、関数呼び出し間でさえありません。他の 3 つの関数を呼び出す関数がある場合、その (外部) 関数が実行されている間、インタープリターは他に何もできません。) インタープリターは基本的に、必要な関数のキューを維持します。実行します。グローバルコードを実行することから始まります(大きな関数呼び出しのように)。次に、何かが起こると (ユーザー入力イベント、経由でスケジュールされたコールバックを呼び出す時間にsetTimeout
達するなど)、インタープリターは必要な呼び出しをキューにプッシュします。それは常にキューの先頭で呼び出しを処理するため、物事が積み重なる可能性があります(あなたのsetInterval
呼び出しのようにsetInterval
、少し特殊 — 前のコールバックがまだ処理待ちのキューにある場合、後続のコールバックはキューに入れられません)。したがって、コードがいつ制御を取得し、いつ制御を解放するか (たとえば、戻ることによって) について考えてみてください。インタープリターは、ユーザーが制御を解放した後、制御を再びユーザーに返す前にのみ、他のことを実行できます。繰り返しになりますが、一部のブラウザー (IE など) では、同じスレッドが UI の描画などにも使用されるため、DOM 挿入 (たとえば) は、制御をブラウザーに戻して取得できるようになるまで表示されません。その絵を描いています。
Web ブラウザーで Javascript を使用する場合、ソリューションの設計とコーディングにイベント駆動型のアプローチを採用する必要があります。典型的な例は、ユーザーに情報を求めるプロンプトです。非イベント駆動型の世界では、次のことができます。
// Non-functional non-event-driven pseudo-example
askTheQuestion();
answer = readTheAnswer(); // Script pauses here
doSomethingWithAnswer(answer); // This doesn't happen until we have an answer
doSomethingElse();
それはイベント駆動型の世界では機能しません。代わりに、次のようにします。
askTheQuestion();
setCallbackForQuestionAnsweredEvent(doSomethingWithAnswer);
// If we had code here, it would happen *immediately*,
// it wouldn't wait for the answer
たとえば、askTheQuestion
ページ上の div をオーバーレイして、さまざまな情報を入力するようにユーザーに促すフィールドを配置し、完了したらクリックする [OK] ボタンを表示することができます。setCallbackForQuestionAnswered
実際click
には「OK」ボタンでイベントをフックします。doSomethingWithAnswer
フィールドから情報を収集し、div を削除または非表示にし、その情報で何かを行います。