なぜsetTimeoutは私のループをキャンセルしないのですか?
質問
私は、JavaScriptの
while
ステートメントが1ミリ秒間に何回変数をインクリメントできるのか気になったので、このスニペットをコンソールに直接書き込んでみました。
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
問題は、永遠に実行されることです。
なぜこのようなことが起こるのでしょうか、また、どのように解決すればよいのでしょうか。
どのように解決するのですか?
これは、JavaScript のワンスレッドという性質に帰着します。 1 . 何が起こるかというと、ほとんどこれです。
- 変数が代入されます。
-
関数をスケジュールし
run = false
. これが実行されるようにスケジュールされます 後 の後に実行されるようスケジュールされています(あるいは、現在アクティブなものは何でも)。 - エンドレスループを持ち、現在の関数の内部にとどまります。
-
エンドレスループの後 (
決して
) の後に
setTimeout()
コールバックが実行されrun=false
.
ご覧のように
setTimeout()
のアプローチではうまくいきません。この問題を回避するために
while
条件で時間をチェックすることで回避できるかもしれませんが、これは実際の計測を改ざんすることになります。
1
少なくとも、より実用的な目的のために、シングルスレッドとして見ることができます。実際には、いわゆるイベントループと呼ばれるものが存在します。このループでは、すべての関数が実行されるまでキューに入れられます。新しい関数をキューに入れると、その関数はキュー内のそれぞれの位置に置かれます。
後
が終了した後、エンジンはキューから次の関数を取り出します。
setTimeout()
で紹介されているようなタイミングを考慮して)次の関数をキューから取り出し、それを実行します。
その結果、どの時点でも1つの関数だけが実行され、実行はかなりシングルスレッド化されます。イベントには例外があり、以下のリンクで説明されています。
参考までに
-
https://stackoverflow.com/a/16757582/1169798
ここでは、同様のシナリオをより詳細に説明しています。
-
https://stackoverflow.com/a/2734311/1169798
JSがシングルスレッドとみなされる場合とそうでない場合について、より詳細な説明があります。
関連
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] JSONPとは何か、なぜ作られたのか?
-
[解決済み] forEachループでasync/awaitを使用する
-
[解決済み] ngModel' は 'input' の既知のプロパティではないため、バインドできません。
-
[解決済み] なぜ ++[[]][+[] +[+[]] は "10" という文字列を返すのでしょうか?
-
[解決済み] React JSX内のループ
-
[解決済み] setTimeout(fn, 0)が役に立つことがあるのはなぜですか?
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptはシングルスレッドであることが保証されていますか?
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] チェックボックスが選択されているかどうかを確認するjQuery
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
-
[解決済み] 兄弟ノードを選択する方法はありますか?
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] $.ajax実行中にローディングイメージを表示する
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?