2017-12-03 2 views
0

私はnested loopまたはelse blockの繰り返しごとに1秒ごとにスリープする必要がある巨大なネストされたforループを持っています。これは通常次のようなコードで実行されます。繰り返しの間に睡眠を持つループ

for (let i=1; i<10; i++) { 
    setTimeout(function timer(){ 
     alert("hello world"); 
    }, i*3000); 
} 

これはあまりにもメモリを消費するので、使用しないでください。

これは、これまでの私のコードです:

for (var i = 0; i < this.data.length; i++) { 
    if (this.data[i].dataTypes.length > 0) { 
     for (var j = 0; this.data[i].dataTypes.length; j++) { 
     //performed each second 
     this.setData(this.data[i].dataName, this.data[i].dataTypes[j]); 
     } 
    } else { 
     //performed each second 
     this.setData(this.data[i].dataName, ""); 
    } 
    } 

どのように私がするので、ネストされたループ、または他のブロックが毎秒実行されることを、それを書き換える必要がありますか?

+0

しかし、私の配列の長さは20000を超えています。確かにそれは行く方法ではない。 – sanjihan

+0

あなたは 'for'ループを使用することを熱望していない場合でも再帰を使うことができますが、いずれの方法も非常に効率的です。 –

+0

コード内に20000のsetTimeoutsを設定しても問題ありませんか? :) – sanjihan

答えて

3

あなたがループに好きではない場合は、行うことができますいずれか

function sleep(n){ 
    return new Promise(res => setTimeout(res, n)); 
} 

async function doStuff(){ 
    for(let element of myList){ 
     doMoreStuff(); 
     await sleep(1000); 
    } 
} 

https://jsfiddle.net/DerekL/y7m0qv51/

または

function doStuff(i){ 
    doMoreStuff(myList[i]); 
    setTimeout(() => doStuff(i + 1), 1000); 
} 

https://jsfiddle.net/DerekL/rh8m6h94/

しかし、あなたが実現する必要があり、これらのどれもより効率的であると考えられる。

1

これを行う1つの方法は、末尾の再帰の形式としてsetTimeout()を使用することです。

var index = 0 
var process = function() { 
     if(something) { 
     do_something(); 
     } else { 
     do_something_else(); 
     } 
    index = index + 1; 
    if(index < this.data.length) { 
     setTimeout(process, 1000); 
    } 
}; 
process(); 

例えば

は、「これは」コールバックに関して、少し気難しいあることに注意してください。 は 'this'がコールバック内で正しく設定されるように 'setTimeout(process.bind(this)、1000)'を使用する必要があります。