美文网首页
node事件循环

node事件循环

作者: 努力学习的小丸子 | 来源:发表于2021-04-18 21:18 被阅读0次

    浏览器事件循环见:https://www.jianshu.com/p/64bbefbe5ae5
    参考:http://lynnelv.github.io/js-event-loop-nodejs
    nodejs中的eventloop 和 浏览器中的eventloop 不一样。

    node事件循环图例:

    https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

    image.png

    各阶段解释:

    • timers: this phase executes callbacks scheduled by setTimeout() and setInterval(). //此阶段执行由 setTimeout 和 setInterval 调度的回调。

    • pending callbacks: executes I/O callbacks deferred to the next loop iteration. //执行 延迟到下一个循环迭代的 I/O 回调。

    • idle, prepare: only used internally.

    • poll: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and setImmediate()); node will block here when appropriate. //检索新的I/O事件;执行与I/O相关的回调(除了close回调、setTimeout调度的回调和setImmediate())之外的几乎所有回调;节点将在适当的时候阻塞这里。

    • check: setImmediate() callbacks are invoked here. //此处调用setImmediate回调。

    • close callbacks: some close callbacks, e.g. `socket.on('close', ...)
      使用setImmediate的目的是不阻塞当前操作,如下不会阻塞for循环:

     trigger(topic,params){
     if(!this.eventMap[topic]){
     return;
     }
     this.eventMap[topic].forEach(item=>{
     // cb();
     item.cb && setImmediate(()=>{item.cb(params)})
     })
     }
    

    node 微任务执行时机:六个阶段中的任意阶段执行完成,都会执行微任务队列中的任务

    image.png

    例子:

    //第一个事件循环,timers中执行
    setTimeout(()=>{
        console.log('timer1')
       // 此处是第二个事件循环,同样是在timers阶段执行
        setTimeout(function(){
            console.log(11111)
            Promise.resolve().then(function() {
                console.log('222')
            })
        },0)
    
        Promise.resolve().then(function() {
            console.log('promise1')
        })
    }, 0)
    //第一个事件循环,timers中执行
    setTimeout(()=>{
        console.log('timer2')
    
        Promise.resolve().then(function() {
            console.log('promise2')
        })
    }, 0)
    

    执行结果:


    image.png

    理解node 事件循环

     function checkFund(){
        if(Math.random()<.5){
            return {msg:'success'}
        }else{
            throw new Error('error');
        }
     }
    // 可以捕捉到error,因为处于一个事件循环中
     try{
         for(let i=0;i<10;i++){
             checkFund();
         }
     }catch(e){
         console.log('catch,',e);
     }
    

    当使用异步

     function checkFund(){
         setTimeout(()=>{
            if(Math.random()<.5){
                return {msg:'success'}
            }else{
                throw new Error('error');
            }
         })
     }
    // 无法捕捉到error,因为处于不同的事件循环中,此时会将error抛到全局,非常不安全
     try{
         for(let i=0;i<10;i++){
             checkFund();
         }
     }catch(e){
         console.log('catch,',e);
     }
    

    node官方推荐的error-first回调

    
     function checkFund(cb){
        if(Math.random()<.5){
            cb(null,{msg:'success'})
        }else{
            cb(new Error('error'))
        }
     }
     for(let i=0;i<10;i++){
        checkFund((err,res)=>{
            if(err){
                console.log('err')
            }
        })
     }
    

    相关文章

      网友评论

          本文标题:node事件循环

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