我想在while循环中添加一个delay/sleep:
我是这样试的:
alert('hi');
for(var start = 1; start < 10; start++) {
setTimeout(function () {
alert('hello');
}, 3000);
}
只有第一种情况是正确的:在显示alert('hi')后,它将等待3秒,然后alert('hello')将显示,但随后alert('hello')将不断重复。
我想要的是,在警报('hello')显示3秒后警报('hi'),然后它需要等待3秒的第二次警报('hello'),以此类推。
在ES6 (ECMAScript 2015)中,您可以使用生成器和间隔迭代延迟。
生成器(generator)是ECMAScript 6的一个新特性,是可以被替换的函数
顿了顿,接着说。调用genFunc不会执行它。相反,它
返回一个所谓的生成器对象,让我们控制genFunc的
执行。genFunc()最初是挂起在它的开始
的身体。方法genObj.next()继续执行genFunc,
直到下一次丰收。
(探索ES6)
代码示例:
Let arr = [1,2,3, 'b'];
let genObj = genFunc();
let val = genObj.next();
console.log (val.value);
let interval = setInterval(() => {
val = genObj.next();
If (val.done) {
clearInterval(间隔);
}其他{
console.log (val.value);
}
}, 1000);
函数* genFunc() {
For (let item of arr) {
收益项;
}
}
所以如果你正在使用ES6,这是实现延迟循环的最优雅的方式(在我看来)。
我认为你需要这样的东西:
var TimedQueue = function(defaultDelay){
this.queue = [];
this.index = 0;
this.defaultDelay = defaultDelay || 3000;
};
TimedQueue.prototype = {
add: function(fn, delay){
this.queue.push({
fn: fn,
delay: delay
});
},
run: function(index){
(index || index === 0) && (this.index = index);
this.next();
},
next: function(){
var self = this
, i = this.index++
, at = this.queue[i]
, next = this.queue[this.index]
if(!at) return;
at.fn();
next && setTimeout(function(){
self.next();
}, next.delay||this.defaultDelay);
},
reset: function(){
this.index = 0;
}
}
测试代码:
var now = +new Date();
var x = new TimedQueue(2000);
x.add(function(){
console.log('hey');
console.log(+new Date() - now);
});
x.add(function(){
console.log('ho');
console.log(+new Date() - now);
}, 3000);
x.add(function(){
console.log('bye');
console.log(+new Date() - now);
});
x.run();
注意:使用警报暂停javascript执行,直到你关闭警报。
它的代码可能比您要求的要多,但这是一个健壮的可重用解决方案。
对于常用的“忘记正常循环”和使用这个组合的“setInterval”包括“setTimeOut”:像这样(从我的实际任务)。
function iAsk(lvl){
var i=0;
var intr =setInterval(function(){ // start the loop
i++; // increment it
if(i>lvl){ // check if the end round reached.
clearInterval(intr);
return;
}
setTimeout(function(){
$(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
},50);
setTimeout(function(){
// do another bla bla bla after 100 millisecond.
seq[i-1]=(Math.ceil(Math.random()*4)).toString();
$("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
$("#d"+seq[i-1]).prop("src",pGif);
var d =document.getElementById('aud');
d.play();
},100);
setTimeout(function(){
// keep adding bla bla bla till you done :)
$("#d"+seq[i-1]).prop("src",pPng);
},900);
},1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
}
PS:理解(setTimeOut)的真实行为:它们都将在同一时间开始“三个bla bla bla将在同一时刻开始倒数”,因此设置不同的超时来安排执行。
PS 2:计时循环的例子,但对于一个反应循环,你可以使用事件,承诺async await ..
因为ES7有一个更好的方法来等待循环:
// Returns a Promise that resolves after "ms" Milliseconds
const timer = ms => new Promise(res => setTimeout(res, ms))
async function load () { // We need to wrap the loop into an async function for this to work
for (var i = 0; i < 3; i++) {
console.log(i);
await timer(3000); // then the created Promise can be awaited
}
}
load();
当引擎到达await部分时,它设置一个超时并停止async函数的执行。然后,当超时完成时,继续执行。这是非常有用的,因为你可以延迟(1)嵌套循环,(2)有条件的,(3)嵌套函数:
异步函数任务(i) {// 3
等待计时器(1000);
console.log('任务${i}完成! ');
}
异步函数main() {
对于(设I = 0;I < 100;I += 10) {
For(令j = 0;J < 10;j++) {// 1
如果(j % 2) {// 2
等待任务(i + j);
}
}
}
}
main ();
函数定时器(ms){返回新的承诺(res => setTimeout(res, ms));}
MDN参考资料
虽然ES7现在被NodeJS和现代浏览器支持,但你可能想用BabelJS编译它,这样它就可以在任何地方运行。