通过例子进行分析:
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2 () {
console.log(async2);
}
console.log('script start');
setTimeout(() => {
console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
console.log('promise1');
reslove();
}).then(function () {
console.log('promise2');
})
console.log('script end');
async1 start
async2
promise1
script end
async1 end
promise2
setTimeOut```
分析结果:
1:js EventLoop 事件循环机制:JavaScript的事件分两种,宏任务(macro-task)和微任务(micor-task)
宏任务:包括整体代码script,setTimeout,setInterval
微任务:Promise.then, process.nextTick(node中)
事件的执行顺序:先执行宏任务,然后执行微任务。任务可以有同步任务和异步任务,同步的进入主线程,异步的进入Event Table并注册函数,异步事件完成后,会将回调函数放入Event Queue中,同步任务执行完成后,会从Event Queue中读取事件放入主线程执行,回调函数中可能还会包含不同的任务,因此会循环执行上述操作。
2:setTimeout:setTimeout不是直接把回调函数放进上述的异步队列中去,而是等定时器的时间到了以后,再把回调函数放到执行异步队列中去。如果此时这个队列已经存在很多任务,则将排在这些任务的后面(这也就是为什么setTimeout不能精准的执行问题)
1:主进程必须是空闲的状态,如果时间到了,主进程不空闲也不会执行回调函数
2:这个回调函数需要等到插入异步队列是前面的异步函数都执行完了,才会执行
3:promise,async/await
1:new Promise是同步任务,会被放到主线程中立即执行,而then()函数是异步任务,会放到异步队列中(当promise状态结束的时候,就会被立即放进异步队列中去)
2:async/await 函数等待 只有当await执行完成以后,才会继续执行后面的代码