美文网首页
nodejs之setTimeout

nodejs之setTimeout

作者: 胖子罗 | 来源:发表于2019-10-27 16:09 被阅读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先执行。

    相关文章

      网友评论

          本文标题:nodejs之setTimeout

          本文链接:https://www.haomeiwen.com/subject/vqtmvctx.html