setTimeout(function(){console.log(1)},1000),
setTimeout(function(){console.log(2)},5000),
setTimeout(function(){console.log(3)},300),
setTimeout(function(){console.log(4)},800)
我有4个定时器,想按照顺序执行,怎么实现呢
setTimeout(function(){console.log(1)},1000),
setTimeout(function(){console.log(2)},5000),
setTimeout(function(){console.log(3)},300),
setTimeout(function(){console.log(4)},800)
我有4个定时器,想按照顺序执行,怎么实现呢
(我觉得你可能想要的是按顺序执行一些异步操作)
想要顺序持续,首先第一涉及到了等待,即 async/await
,于是需要用 Promise
封装,第二点涉及到 Promise
顺序执行,通常使用 Array.reduce
来实现:
const queue = [
() => new Promise(r => setTimeout(() => r(), 1000)),
() => new Promise(r => setTimeout(() => r(), 5000)),
() => new Promise(r => setTimeout(() => r(), 300)),
() => new Promise(r => setTimeout(() => r(), 800))
]
await queue.reduce(async (memo, process, i) => {
await memo
await process()
console.log(i + 1)
}, undefined)
1.启动定时器
2.定时器到时间任务执行
启动四个定时器的顺序
四个定时器的任务执行顺序
定时器之所以叫定时器,是针对时间的,时间上有顺序,任务的执行就有顺序。既然规定了时间上的顺序,有要求不按事件顺序,那用定时器干嘛呢。要么不用定时器,要么用时间控制顺序。
要想让延时定时器按1234的打印顺序执行的话有以下几个方法:
将延时定时器函数封装成Promise对象并使用async/await语法同步调用
(async() => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(1000);
console.log(1);
await delay(5000);
console.log(2);
await delay(300);
console.log(3);
await delay(800);
console.log(4);
})();
将定时器回调函数放在队列中封装后递归执行
function queue() {
var args = arguments;
if (!args.length) return;
var options = Array.prototype.shift.call(args);
var that = this;
setTimeout(function() {
options.callback.call(that);
queue.apply(that, args);
}, options.delay);
}
queue({
callback: function() {
console.log(1);
},
delay: 1000
}, {
callback: function() {
console.log(2);
},
delay: 5000
}, {
callback: function() {
console.log(3);
},
delay: 300
}, {
callback: function() {
console.log(4);
},
delay: 800
});
同样是先将定时器回调函数放入队列,然后把每个定时器的延时时间叠加后执行以达到按顺序调用的目的
function queue() {
var delay = 0;
var that = this;
for (var i = 0; i < arguments.length; ++i) {
delay += arguments[i].delay;
setTimeout(function(callback) {
callback.call(that);
}, delay, arguments[i].callback);
}
}
queue({
callback: function() {
console.log(1);
},
delay: 1000
}, {
callback: function() {
console.log(2);
},
delay: 5000
}, {
callback: function() {
console.log(3);
},
delay: 300
}, {
callback: function() {
console.log(4);
},
delay: 800
});
采用纯 setTimeout 实现,大概应该这么写
setTimeout(function () {
console.log(1);
setTimeout(function () {
console.log(2);
setTimeout(function () {
console.log(3);
setTimeout(function () {
console.log(4);
}, 800);
}, 300);
}, 5000);
}, 1000);
也就是在每次 timeout 到时间的时候启动下一个 timer。
实际每次调用的行为基本致,如果封装成 Promise,可能更容易看一些
function runAfter(fn, milliseconds) {
return new Promise(resolve => {
setTimeout(() => resolve(fn()), milliseconds);
});
}
runAfter(() => console.log(1), 1000)
.then(() => runAfter(() => console.log(2), 5000))
.then(() => runAfter(() => console.log(3), 300))
.then(() => runAfter(() => console.log(4), 800));
不过既然都封闭成 Promise 了,不如用 await 看起来更清晰
// 多数情况下,await 必须在 async 函数中使用,所以封个 IIFE。
// 注支持顶层 await 的环境不需要如此
(async () => {
await runAfter(() => console.log(1), 1000);
await runAfter(() => console.log(2), 5000);
await runAfter(() => console.log(3), 300);
await runAfter(() => console.log(4), 800);
})();
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
你想要按照什么顺序执行,想要按照
1,2,3,4
这种执行吗?这种方式对你们前端来说的话,可以用
Promise
,不用这个自己实现一个也没啥问题啊,我随便写个例子: