JavaScript--EventLoop + Promise + Async/Await

刚学了JavaScript的EventLoop,并且混上Promise和Async/Await,在此作下总结

  1. 总共可分三种队列,第一是宏任务队列,第二是微任务队列,第三是专为process.nextTick创建的队列
  2. 三个队列的执行顺序是 宏-->nextTick-->微,之后不断循环
  3. 普通的语句(如console),函数和new的Promise中的语句,await修饰的语句放到宏队列
  4. Promise的then,await修饰语句之后的语句放在微队列,并且环境不同可能then和await的顺序也不同,在浏览器环境中平级,在node环境中then优先
  5. process.nextTick内的语句放在专属队列
  6. setTimeout,setInterval的作用是在指定时间后将内部语句放在下一次循环的宏任务队列
  7. 多个Promise后的then交替添加到微队列
new Promise(resolve => {
    console.log(1)
    resolve()
}).then(()=>{
    console.log(2)
}).then(()=>{
    console.log(3)
})
new Promise(resolve => {
    console.log(4)
    resolve()
}).then(()=>{
    console.log(5)
}).then(()=>{
    console.log(6)
})

输出

1
4
2
5
3
6
  1. 理解async/await
async function fun() {
    await console.log(1)
    console.log(2)
}
fun()
同
new Promise(resolve => {
    console.log(1)
    resolve()
}).then(()=>{
    console.log(2)
})
  1. setImmediate同setTimeout(…, 0)表示立即将语句放入下一个宏队列,不过两者顺序有待研究,并非完全随机
这段代码最外层的setImmediate和setTimeout顺序不定,因此输出结果不一定
setImmediate(function A() {
    console.log(1);
    setImmediate(function B(){
        console.log(2);
        process.nextTick(function () {
            console.log('nextTick');
        });
        setTimeout(function t1() {
            console.log('t1');
        })
    });
});
setTimeout(function t2() {
    console.log('t2');
    setTimeout(function t3() {
        console.log('t3');
    });
    setTimeout(function t4() {
        console.log('t4');
    });
}, 0);

这段代码setImmediate永远在setTimeout之后
async function async1() {
    console.log("async1 start");
    await  async2();
    console.log("async1 end");
}
async  function async2() {
    console.log( 'async2');
}
console.log("script start");

async1()
new Promise(function (resolve) {
    console.log("promise1");
    resolve();
}).then(function () {
    console.log("promise2");
});

process.nextTick(()=>{
    console.log("process")
})
console.log('script end');
setImmediate(()=>{
    console.log("setImmediate")
})
setTimeout(()=>{
    console.log("settimeout");
},0)

望大佬解惑
10. 终极实战

async function async1() {
    console.log("async1 start");
    await  async2();
    console.log("async1 end");
}
async  function async2() {
    console.log( 'async2');
}
console.log("script start");

async1()
new Promise(function (resolve) {
    console.log("promise1");
    resolve();
}).then(function () {
    console.log("promise2");
});

process.nextTick(()=>{
    console.log("process")
})
console.log('script end');
setImmediate(()=>{
    console.log("setImmediate")
})
setTimeout(()=>{
    console.log("settimeout");
},0)

队列执行start
第一轮:

current task:“script start”,“async1 start”,‘async2’,“promise1”,“script end”
micro task queue:[async,promise.then,process]
macro task queue:[setTimeout,setImmediate]

第二轮

current task:process,async1 end ,promise.then
micro task queue:[]
macro task queue:[setTimeout,setImmediate]

第三轮

current task:setTimeout,setImmediate
micro task queue:[]
macro task queue:[]

最终结果:[script start,async1 start,async2,promise1,script end,process,async1 end,promise2,setTimeout,setImmediate]

“async1 end”,"promise2"之间的优先级,因平台而异

详情
https://juejin.im/post/5c9a43175188252d876e5903?utm_source=gold_browser_extension#heading-5

上一篇:Vue响应式原理踩坑


下一篇:MutationObserver