Promise,async和await的⾯试题
Promise,async和await的⾯试题
async和await的基本原理
async
async是Generator函数的语法糖,使⽤async表⽰,在函数内部使⽤await表⽰异步,相对于Generator,async做了⼀些改进:
Generator的执⾏需要依靠执⾏器,async内置执⾏器,⾃动执⾏
async代替了*,await代替了yield,语义化更好
async函数返回值是⼀Promise对象
await
await意思是async wait(异步等待)。这个关键字只能在使⽤async定义的函数⾥⾯使⽤。await会解析Promise对象的值,async会等所有的await命令的Promise对象执⾏完,才会发⽣状态的改变。
⼀、关于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)
});
console.log(5);
});
console.log(6);
执⾏catch时,状态已经变为resolved,就不会执⾏catch的回调函数,⽽执⾏默认的成功的回调函数:onResolved : value => value。⼀定要注意这⾥直接把catch的回调函数替换了,所以不会再执⾏console.log(err);了。
1
3
4
6
5
resolve
2
4.
console.log('start');
setTimeout(()=>{
console.log('time');
});
const p1 =new Promise((resolve, reject)=>{
console.log('resolve1');
}).then(()=>{
console.log('resolve');
});
console.log('end');
start
resolve1
end
time
由于没有调⽤resolve,所以该promise函数⼀直处于pending状态,并不会执⾏.then函数。
⼆、关于async和await
async 函数返回⼀个 Promise 对象,当函数执⾏的时候,⼀旦遇到 await 就会先返回(交出线程,跳出 async 函数体),等到触发的异步操作完成,再接着执⾏函数体内后⾯的语句。
await后⾯的语句会⽴即执⾏,返回promise时,由于考虑到异步操作,且下⼀⾏语句需要知道结果才能执⾏,所以返回的promise会等后⾯的同步语句执⾏完之后放⼊微队列中。
1.
async function async1(){
console.log('async1 start');
await async2();会先执⾏async2函数,然后跳出async1,执⾏同步语句,然后将返回的promise放⼊微队列
// 会⽴即放⼊微队列,相当于.then,所以会在promise2的前⾯
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
await和async使用方法async1 start
async
promise1
promise3
script end
promise2
promise4
testAwait
async1 end
setTimeout
三、solve()会造成三次微队列⼊队延迟先来看⼀段代码,下⾯这段代码输出 0,1,2,3,4,5,6
console.log(0);
solve(4);
}).then((res)=>{
console.log(res);
});
console.log(1);
}).then(()=>{
console.log(2);
}).then(()=>{
console.log(3);
}).then(()=>{
console.log(5);
}).then(()=>{
console.log(6);
});
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论