[解決済み】forループのsetTimeoutで連続した値が表示されない【重複あり
質問
こんなスクリプトがあります。
for (var i = 1; i <= 2; i++) {
setTimeout(function() { alert(i) }, 100);
}
しかし
3
は2回ともアラートされ、代わりに
1
では
2
.
を渡す方法はありますか?
i
文字列として関数を書かずに?
どのように解決するのですか?
タイムアウト機能ごとに、"i"の別個のコピーが存在するように手配する必要があります。
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, 100);
}
for (var i = 1; i <= 2; ++i)
doSetTimeout(i);
もしこのようなことをしなければ(この同じアイデアの他のバリエーションもあります)、各タイマーハンドラ関数が 共有 は、同じ変数 "i"です。 ループが終了したとき、"i"の値はどうなっているでしょうか? それは3です! 中間的な関数である コピー の値が作成されます。タイムアウトハンドラはそのコピーのコンテキストで作成されるので、使用するプライベートな "i" を持ちます。
編集
- いくつかのタイムアウトを設定すると、すべてのハンドラが同時に起動するという事実に対して、いくつかの混乱が見られるというコメントがありました。重要なのは、このような処理は
設定
タイマーの呼び出し、つまり
setTimeout()
- はほとんど時間がかかりません。つまり、システムに "1000ミリ秒後にこの関数を呼び出してください" と伝えると、タイマーキューにタイムアウト要求をインストールする処理が非常に速いため、ほぼ即座に返されます。
したがって、もし 継承 のように、タイムアウト要求が行われ、遅延時間の値がそれぞれ同じである場合、その時間が経過すると、すべてのタイマーハンドラが次々と呼び出されることになります。
もし、一定時間ごとにハンドラを呼び出す必要があるのであれば、以下のような方法があります。
setInterval()
と全く同じように呼び出されます。
setTimeout()
あるいは、タイムアウトを設定し、その時間に反復カウンタを乗じることもできます。つまり、私のサンプルコードを修正することです。
function doScaledTimeout(i) {
setTimeout(function() {
alert(i);
}, i * 5000);
}
(ただし
100
ミリ秒のタイムアウトでは、効果があまり現れないので、5000に増やしました)。の値は
i
は基本遅延値に乗算されるので、ループ内でこれを5回呼び出すと、5秒、10秒、15秒、20秒、25秒の遅延が発生することになります。
更新
ここで2018年、よりシンプルな代替案があります。関数よりも狭いスコープで変数を宣言する新しい機能により、そのように修正すれば元のコードは動作します。
for (let i = 1; i <= 2; i++) {
setTimeout(function() { alert(i) }, 100);
}
は
let
宣言は
var
が存在することになり、それ自体が
i
ループの各反復のために。
関連
-
[解決済み】JavaScriptで「無効な日付」のDateインスタンスを検出する
-
[解決済み] 正規表現で変数を使うには?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] event.preventDefault() vs. return false
-
[解決済み] JavaScriptで文字列をbooleanに変換するにはどうしたらいいですか?
-
[解決済み] jQueryの「exists」関数はありますか?
-
[解決済み] HTML5のlocalStorageにオブジェクトを格納する方法は?
-
[解決済み] .prop() vs .attr()
-
[解決済み] モバイル端末の検出にはどのような方法がありますか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Heroku:ノードアプリで「このアプリにはデフォルトの言語が検出されませんでした」エラーがスローされる
-
[解決済み】TypeError: $(...).DataTable は関数ではありません。
-
[解決済み] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングした
-
[解決済み】webpack-dev-serverにリモート接続すると、「Invalid Host header」というメッセージが表示されます。
-
[解決済み】Uncaught SyntaxError: JSON の位置 0 に予期しないトークン u があります。
-
[解決済み】PhantomJS 2.1.1を使用してReactJSアプリケーションをレンダリングできない理由とは?
-
[解決済み】Babel NodeJS ES6: SyntaxError: 予期しないトークンのエクスポート
-
[解決済み】JavaScriptで関数が存在するかどうかを確認する方法は?
-
[解決済み】中央値の計算 - javascript
-
[解決済み] ループ内のJavaScriptクロージャ - シンプルな実用例