浏览器中的EventLoop
嘿,你觉得下面的代码运行结果是什么呢?
console.log('start')
setTimeout( function () {
console.log('setTimeout')
}, 0 )
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('end')
可以先尝试进行如下分析
1.先将同步执行的代码找出,首先打印的一定是start end
2.setTimeout、Promise是否有优先级 还是根据顺序来执行?
运行一下代码,答案是:start、end、promise1、promise2、setTimeout
需要理解的知识点
1.执行栈
javascript是单线程,也就是只有一个主线程,主线程有一个栈,每一个函数执行时都会生成新的execution context(执行上下文),执行上下文会包含一些当前函数的参数、局部变量之类的信息,它会被推入栈中,running execution context(正在执行的上下文)始终处于栈的顶部。当函数执行完后,它的执行上下文会从栈弹出

function bar(){
console.log('bar')
}
function foo(){
console.log('foo');
bar();
}
foo();
执行过程中栈的变化:

2.宏任务 setTimeout、setImmediate
微任务 promises、processs.nextTick、MutationObserver
3.整个最基本的Event Loop如图所示
- queue可以看做一种数据结构,用以存储需要执行的函数
- setTimeout注册的函数,等到期后进入task队列
- 其余API注册函数直接进入自身对应的macrotask/microtask队列
- Event Loop继续检查microtask队列是否为空,依次执行直至清空microtask队列
- 执行macrotask队列

Node中的EventLoop
Node.js也是单线程的Event Loop,但是它的运行机制不同于浏览器环境

根据上图,Node.js的运行机制如下
1.V8引擎解析javascript脚本 2.解析后的代码 调用node API 3.libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎 4.V8引擎再将结果返回给用户
整个最基本的Event Loop 如图所示

练习
setTimeout(()=>{
console.log('timeout1')
Promise.resolve().then(data=>{
console.log('promise2')
})
})
Promise.resolve().then(()=>{
console.log('promise1')
setTimeout(()=>{
console.log('timeout2')
})
})
let fs = require('fs')
fs.readFile('a.txt','utf-8',()=>{
setTimeout(()=>{
console.log('timeout2')
},0)
setImmediate(()=>{
console.log('setImmediate')
})
})
运行一下吧 看下结果是否你想的呢???