nodejs之setTimeout
2019-10-27 本文已影响0人
胖子罗
问题一:如何实现一个循环定时执行的逻辑?
比如我有1000个请求,我想每一秒发一个。
const request = function(){
for(let i=0;i<1000;i++){
setTimeout(function(){
console.log('doRequest:'+i)
},1000)
}
}
request()
上面代码可能不能实现预期效果,实际是到了1s后同时发了1000条请求。
为什么会这样?我们先看看setTimeout到底做了什么事情?
可参考这篇文章:https://blog.csdn.net/THEANARKH/article/details/88374203
从文章分析结果我们可以知道setTimeout实际就是提前将回调函数添加到一个定时器的回调事件队列中,等待定时器时计时超时的时候函数才会被执行。
所以我们这个例子中实际当前tick只是会一次性将1000个请求加入到回调事件队列中,等到1s的tick到来时一次性执行这一组回调函数。
正确可参考实现代码:
const sleep = function (ms){
return new Promise(resolve => setTimeout(resolve, ms))
}
const request = async function(){
for(let i=0;i<1000;i++){
console.log('request:'+i)
await sleep(1000)
}
}
通过promise+setTimeout实现一个sleep,然后使用await等待promise的timeout到时间再继续执行下一次for循环。
问题2:setTimeout(fn,0)和setImmediate到底谁先执行?
const doTestImmediate = function(){
console.log('doTestImmediate')
}
const doTestTimeout = function(){
console.log('doTestTimeout')
}
setImmediate(doTestImmediate)
setTimeout(doTestTimeout,0)
运行结果1:
ideojjdeMacBook-Pro-6:asmp-ai-api videojj$ node test.js
doTestTimeout
doTestImmediate
运行结果2:
videojjdeMacBook-Pro-6:asmp-ai-api videojj$ node test.js
doTestImmediate
doTestTimeout
总体上结果是随机的,不一定谁先执行。具体原因可参考这篇文章:
https://segmentfault.com/a/1190000013102056?utm_source=tag-newest
程序运行后看执行到目标代码时机,setTimeout是以毫秒为单位计时,如果执行的时机已经过了1ms则setTimeout先执行,如果没到则setImmediate先执行。