インデックス/反復数に従ってForループで間隔時間を動的に変更する方法は?


12

コメントできなかったので、この投稿を強要されました。私は正確に1秒または1000ミリ秒を遅延/待機する以下のコードを取得しました-

let n = 5;
for (let i=1; i<n; i++)
{
  setTimeout( function timer()
  {
      console.log("hello world");
  }, i*1000 );
}

しかし、どうすれば固定の1000ミリ秒ではなくi * 1000秒遅延させることができるので、待機は反復回数に依存しますか?

たとえば、n = 5の場合、最初の反復で1秒のループ遅延が必要です。2番目の反復で2秒、以下同様です。最後の遅延は5秒です。


2
だからあなたは9つのタイマーを作りたいですか?もしそうなら、あなたのコードはあなたが求めていることをします。正確に3秒待機しません。実際、タイマーは正確ではありません。
Scott Marcus

1
あなたの質問は意味がありません
DanStarns '10 / 10/4

2
codepen:codepen.io/Connum/pen/BaaBMwWでコードを試してみただけで3000ms間隔で9つのメッセージが表示されるです。
ConstantinGroß19年

1
そもそもsetTimeoutがどのように機能するのか理解していないようです。これは「遅延」ではありません。現在、アラートは3秒間隔で取得しています。すでに3000を掛けているためです。iそうしないと、すべてのアラートが同時に取得されます。
04FS、

3
最後の文を太字にするために質問を編集することは、実際にはあなたのケースを助けません。これで、複数のコメンテーターから、コードがすでに求めていることを実行していることがわかりました(または、意図した結果ではない場合、実際に何を求めているのかは明確ではありません)。
コンスタンティングロース

回答:


6

これはすぐに表示され、次に1秒後、2秒後、3秒後などに表示される関数です。特別な計算は不要です。プロミスは必要ありません。

const n = 5;
let cnt=0;

function show() {
  console.log("call "+cnt,"delay: ",cnt,"sec");
  cnt++;
  if (cnt > n) return; // we are done
  setTimeout(show, cnt*1000 ); // cnt seconds later
}
show()


1
あなたの答えを逃したことを非常に残念に思って、たくさんのコメント、誤解、答えがありました...とにかく私はあなたがあなたの時間のおかげで私に尋ねた質問を解決した最初のものだったので私はあなたの答えを選びました。
Mike

@マイクロル。他のソリューションはそれ自体で有用なので、受け入れに感謝します
mplungjan

PavanはES6構文でも同じです。読みにくいですが、実際は同じです。それを作るための彼の編集は、私が私が書いたと同時に行われたものです:)
mpungjan

8

このタスクは、promise、リアクティブストリーム、その他のクールなツールで解決できますが(まだ、ワーカーの使用はまだ提案されていません!)、少しの算術演算で解決することもできます。

つまり、1秒、前の1秒+ 2秒、前の1秒+ 3秒のように、タイムアウトを順番に設定します。このシーケンスは、1、3、6、10、15 ...であり、その式はa[n] = n * (n + 1) / 2です。知っています...

let n = 6;
console.log(new Date().getSeconds());

for (let i = 1; i < n; i++) {
  setTimeout(function timer() {
    console.log(new Date().getSeconds());
  }, 1000 * i * (i + 1) / 2);
}


数学者はまだ生きています!! :)
ビラルSiddiqui

5

async / await(Promises)を使用して、コードをシリアル化することができます。

const waitSeconds = seconds => new Promise(resolve => setTimeout(resolve, seconds))

async function main () {
 let oldDate = new Date()
 let newDate
 
 /* 
  * If you put 'await' inside the loop you can synchronize the async code, and simulate
  * a sleep function
  */
 for (let i=1; i<5; i++) {
    await waitSeconds(i*1000)
    newDate = new Date()   
    console.log(`Loop for i=${i}, elapsed=${moment(newDate).diff(oldDate, 'seconds')} seconds`)
    oldDate = newDate
 }
 
 console.log('End')
}

main()
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>


5

質問xDを解読するのに少し時間がかかりましたが、これでいいですか?

これにより、毎回i * 1000の遅延でconsole.logが起動し続けます。したがって、最初は1秒(1 * 1000)になり、次は2秒になります。

let i = 0;
loop = () => {
  setTimeout(() => {
    console.log(new Date()); // for clarity
    i++;
    if (i < 10) {
      loop();
    }
  }, i * 1000)
};
loop();


たとえば、n = 5の場合、最初の反復で1秒のループ遅延が必要です。2番目の反復で2秒、以下同様です。最後の遅延は5秒です。
Mike

うん、これは1回目の反復では1秒、2回目では2秒というように遅延します。それを試してください
Pavan Skipo

説明がコードと一致しません。しかし、それは仕事をしていません
mplungjan

3

ループはタイムアウト機能が完了するのを待ちません。したがって、ループが実行されると、インデックスごとにアラートがスケジュールされます。

インデックスに従って実行され、同時にスケジュールされる関数を使用できます。3秒の違いが感じられます。

function test(i){
    setTimeout( function timer(){
        console.log("hello world" + i);
    }, i*3000);
}
for (let i=1; i<4; i++) {
   test(i);
}

3

forループの代わりに再帰呼び出しを使用する

let i=1;
function a(i) {
  if (i > 5)
    return
  else
    b("message", i)
}

function b(s, f) {
  setTimeout(function timer() {
    console.log(s + " " + f + " seconds");
  }, f * 1000);
  a(++i);
}
a(i);


たとえば、n = 5の場合、最初の反復で1秒のループ遅延が必要です。2番目の反復で2秒、以下同様です。最後の遅延は5秒です。
Mike
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.