我们都知道js是一个 单线程的 非阻塞的语言,那么js的运行机制是怎样的呢?让我们通过本篇文章来学习一下吧
执行栈与事件队列
我们都知道js中有同步代码也有异步代码,其中执行栈就是用来存放同步代码的,;js自上向下按顺序执行时,遇到同步代码就将其存入到执行栈中,遇到异步代码如定时器时,js并不会等到其执行完毕而是将其存放到另一个队列中,我们称之为事件队列;js会将执行栈中的事件执行完后,再去事件队列中查看是否有要执行的元素,如果有就将其取出到执行栈中执行,执行完毕后再次去事件队列中…以此循环.这样我们就可以明白下面的代码为什么明明将定时器时间设为 0 秒却还是先输出22 再输出11了
setTimeout(()=> {
console.log("11");
},0)
console.log("22");
macro task(宏任务) 与micro task(微任务)
上面我们了解了事件队列,在事件队列中又分为了两个栈,即宏任务栈与微任务栈,两者中先执行的是微任务栈中的事件,然后才是宏任务栈中的事件;那么哪些任务是宏任务,哪些又是微任务呢;这里对常见的一些异步事件进行一个简单的分类 微任务:promise的then方法 注意:创建Promise对象是一个同步事件;宏任务: 计时器、ajax、读取文件;
node.js提供的异步函数
process.nextTick()和setImmediate()
process.nextTick()执行在同步代码后,异步代码前;即执行栈中的事件执行完毕后,js就会去执行process.nextTick()中的事件,然后再去执行事件队列中的事件;
setImmediate的执行一般是在所有程序的最后
总结
由上述内容,我们可以得出js的执行顺序: 同步 > process.nextTick > 异步(微任务 > 宏任务) > setImmediate,大家可以想想下面这段代码的输出是什么,将答案写在评论区,交流一下自己的想法
process.nextTick(() => {
console.log(6);
})
setImmediate(()=> {
console.log(7);
})
console.log(1);
setTimeout(()=> {console.log(2)},0)
setTimeout(()=> {console.log(3)},0)
setTimeout(()=> {console.log(4)},0)
console.log(5)