事件循环(消息队列)

js代码运行在单个线程上,所以要避免阻塞线程。

事件循坏要不断的检查调用堆栈( LIFO队列,后进先出 )

每次迭代中的事件循坏都会检查堆栈中的东西是否为空。

const bar = ()=>{ console.log('bar') }
const baz = ()=>{ console.log('baz') }
const foo = ()=>{
    console.log('foo')
    bar()
    baz()
}
foo()   // foo   bar   baz
// 执行的顺序
 foo() → console.log('foo') → bar() → console.log('bar') → baz() → console.log('baz')

如何将函数推迟知道堆栈被清空 --- 消息队列

比如setTimeout()中的回调函数,用户点击事件等都会放到消息队列中。

事件循环会赋予调用堆栈的优先级,一旦为空,就会处理消息队列中的东西

const bar = ()=>{ console.log('bar') } 
const baz = ()=>{ console.log('baz') } 
const foo = ()=>{
    console.log('foo')
    setTimeout(bar, 0)
    baz()
}
foo();  // foo   baz   bar
先执行堆栈,后执行消息队列
foo() → console.log('foo') → setTimeout() → baz() → console.log('baz') → bar() → conosole.log('bar')

promise会排在所有堆栈的后面,消息队列的最前面

const bar = ()=>{ console.log('bar') }
const baz = ()=>{ console.log('baz') }
const foo = ()=>{
    console.log('foo')
    setTimeout(bar, 0)
    new Promise( (res, rej)=>{
        res('在baz之后,bar之前')
    } ).then( res=>consle.log(res) )
    baz()
}

foo(); // foo  baz  在baz之后,bar之前  bar

process.nextTick():告诉JS,当前堆栈调用结束后,要尽快调用这个函数,而不是排到消息队列中

const bar = ()=>{ console.log('bar') }
const baz = ()=>{ console.log('baz') }
const foo = ()=>{
    console.log('foo')
    setTimeout(bar, 0)
    new Promise( (res, rej)=>{
        res('在baz之后,bar之前')
    } ).then( res=>console.log(res) )
    // process.nextTick(()=>{console.log('end')})
    baz()
}
// process.nextTick(()=>{console.log('end')})
foo(); // foo  baz  end  在baz之后,bar之前  bar    //结果一样

setImmediate( ()=>{  } ):这个执行顺序一般在setTimeout()后执行,当然也有其他因素,暂未发现

详见nodejs官网:了解 setImmediate()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值