JS中await、async、宏任务、微任务的执行顺序

宏任务和微任务

1、宏任务和微任务都是队列(先进先出),宏任务有script、setTimeout、setInterval等,微任务有Promise.then/ catch/finally、process.nextTick等。
2、一个宏任务执行完,判断是否有可执行的微任务,有则执行完所有微任务,否则执行下一个宏任务。
宏任务和微任务

async和await

1、async修饰符:async修饰的函数,默认返回 new Promise对象的resolve内容(若被async修饰的函数无返回值,则最终无返回值)。如此调用 async修饰的函数,可以直接使用then获取resolve值,用catch获取reject值,如

async function fun0(a) {
    return new Promise((resolve, reject)=>{
        if(a>2) resolve("haha")
        else reject("hehe")
    })
}

fun0(3).then( x => { console.log(x) }).catch(e=>console.log(e))  //输出"haha"
fun0(1).then( x => { console.log(x) }).catch(e=>console.log(e))  //输出"hehe"

2、async方法内部,当程序执行到await方法时,会阻塞await方法后面的程序,进入await方法内部并执行到return前,然后跳出该async方法,执行与该async方法并列的同步任务。

async function test1() {
	console.log('start test1');
	console.log(await test2());
	console.log('end test1');
}
async function test2() {
	console.log('test2');
	return await 'return test2 value'
}
test1();

console.log('start async');

setTimeout(() => {
	console.log('setTimeout');
}, 0);

new Promise((resolve, reject) => {
	console.log('promise1');
	resolve();
}).then(() => {
	console.log('promise2');
});

console.log('end async');

输出结果:
start test1
test2
start async
promise1
end async
promise2
return test2 value
end test1
setTimeout

分析:
(1)执行test1函数,执行console.log(‘statr test1’);
(2)遇到await,先执行右边test2中的console.log(‘test2’),中断了后面的代码,执行test1外面的同步代码;
(3)执行console.log(‘start async’);
(4)遇到setTimeout,推到到下个宏任务队列中;
(5)执行Promise里面的同步代码console.log(‘promise1’);
(6)运行到promise().then,发现是promise对象,推到微任务队列中;
(7)执行console.log(‘end async’);
(8)test1外面的同步代码执行结束后,回到test1中,console.log(await test2())执行完成后返回Promise {: “return test2 value”},是promise对象,推到微任务队列中;
(9)此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log(‘promise2’),后执行console.log(‘return test2 value’);
(10)执行test2完成后,后面的代码不再阻塞,执行console.log(‘end test1’);
(11)执行下个宏任务,即console.log(‘setTimeout’)。

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页