关于async/await、promise和setTimeout执行顺序

185 阅读2分钟

通过例子进行分析:


    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执行完成以后,才会继续执行后面的代码