JS是单线程,所以理论是会出现阻塞的问题,为了解决该问题,所以通过单线程来模拟多线程进行解决。
同步任务:在程序中可以立即执行的任务,比如console.log等,可以立刻看到结果。
异步任务:在程序中需要等待才能看到结果的任务,比如接口请求、定时器、延时器等。
代码从上向下执行进行执行栈,会判断任务是同步还是异步。
同步任务:则进入主线程,同步任务全部执行完毕,获取任务结果。
异步任务:则进入任务表中注册函数,当指定的函数执行完成后,注册回调函数,任务表则将这个函数移到任务队列当中。主线程内任务全部执行完成后,会去任务队列中读取对应函数,进入主线程执行,
事件监听会监听异步任务的状态,如果可以执行回调,就会将对应的任务放到任务队列里。
上述过程会不断循环,这就是任务循环
宏任务与微任务
首先:宏任务与微任务都属于异步任务
先执行微任务后执行宏任务
2.宏任务与微任务有哪些
宏任务
I/O、setTimeout、setInterval、setImmediate
微任务
process.nextTick 、Promise.then/.catch/.finally
3.宏任务与微任务的执行顺序
JavaScript是单线程的,常用的任务分为同步任务和异步任务。在每轮事件循环中,主线程会先执行完同步任务,再执行异步任务。
整体JavaScript代码将作为一个宏任务执行,先将同步任务进入主线程执行,异步任务进入事件表(Event Table)并注册回调函数(如:success、then、catch等)。当异步事件完成,回调函数进入事件队列等待被调用。而来自不同任务源的任务会进入不同的任务队列。其中setTimeout与setInterval是同源的。
js引擎Monitoring Process进程会不断的检查主线程执行栈是否为空,一旦为空,就会检查事件队列中是否有等待被调用的函数,如果有,主线程将依次读取回调函数并调用。否则执行下一轮事件循环。
微任务存到一个数组中,红任务存到链表中。
在每轮事件循环中微任务队列的优先级高于宏任务队列。微任务队列中排队的所有微任务都在同一周期内处理,而这些微任务本身也可以将其他微任务添加到微任务队列中中执行,只有这些微任务全部执行完成时,才会执行下一个宏任务。
4.案例
案例1
案例2
process.nextTick()先于Promise.then()执行, setTimeout()与setImmediate()执行顺序取决于setTimeout的执行周期与设备性能。
process.nextTick 属于 idle观察者
idle观察者 > IO观察者 > check观察者
注意注意
不同版本的node 执行顺序不一样
注意: 以上代码在 node11 以下版本的执行结果(先执行所有的宏任务,再执行微任务)
注意: 以上代码在 node11 及浏览器的执行结果(顺序执行宏任务和微任务)