Promise,async和await的面试题
一、关于Promise的执行顺序
创建Promise是同步的,当执行完resolve();
后,状态变为resolved
,后面的.then
立即放入微队列,第二个.then
放入第一个.then
返回promise对象的缓存队列中(并不是微队列)。
1.
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
return new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
}) 这里返回的对象是最后一个.then返回的对象,第一次时状态为‘pending’
.then(() => {
所以第一次这里会缓存起来并不是加入队列
console.log("外部第二个then");
});
2.
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
}) 这里返回的是undefined 的promise对象
.then(() => {
第一次时这个promise对象已经是resolved了,所以立即加入队列
console.log("外部第二个then");
});
3.
console.log(1);
setTimeout(() => {
console.log(2);
});
new Promise(resolve => {
console.log(3);
resolve('resolve');
console.log(4);
reject('error')
}).catch((err) => {
console.log(err);
}).then((res) => {
console.log(res)
});
Promise.resolve().then(() => {
console.log(5);
});
console.log(6);
执行catch时,状态已经变为resolved,就不会执行catch的回调函数,而执行默认的成功的回调函数:onResolved : value => value
。一定要注意这里直接把catch的回调函数替换了,所以不会再执行console.log(err);
了。
1
3
4
6
5
resolve
2
二、关于async和await
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回(交出线程,跳出 async 函数体),等到触发的异步操作完成,再接着执行函数体内后面的语句。
await后面的语句会立即执行,返回promise时,由于考虑到异步操作,且下一行语句需要知道结果才能执行,所以返回的promise会等后面的同步语句执行完之后放入微队列中。
1.
async function async1(){
console.log('async1 start');
await async2(); 会先执行async2函数,然后跳出async1,执行同步语句,然后将返回的promise放入微队列
console.log('async1 end');
}
async function async2(){
console.log('async');
}
console.log('script start');
setTimeout(function (){
console.log('setTimeout');
},0);
async1();
new Promise(function(resolve){
console.log('promise1');
resolve();
}).then(function(){
console.log('promise2');
});
console.log('script end');
script start
async1 start
async
promise1
script end
async1 end
promise2
setTimeout
2.
async function async1() {
console.log('async1 start');
const result = await async2();
console.log(result);
// 会先执行async2函数, 然后跳出async1, 同时将返回的promise放入微队列
console.log('async1 end');
}
async function async2() {
console.log('async');
return "testAwait";
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
new Promise(function(resolve) {
console.log('promise3');
resolve();
}).then(function() {
console.log('promise4');
});
console.log('script end');
script start
async1 start
async
promise1
promise3
script end
promise2
promise4
testAwait
async1 end
setTimeout