async和await
2020-01-28 本文已影响0人
agamgn
前言
异步操作一直是Javascript中重要的一部分,从回调到Promise再到async/await,异步操作是越来越简单,现在来看看async和await的用处。
一、async/await是什么
async/await是Javascript中对于异步操作的解决方案,被称为终极解决方案,他是 Generator 函数的语法糖,关于Generator 函数参考Generator使用。其有以下特点:
- async/await 是一种编写异步代码的新方法。之前异步代码的方案是回调和 promise。
- async/await 是建立在 promise 的基础上。
- async/await 像 promise 一样,也是非阻塞的。
- async/await 让异步代码看起来、表现起来更像同步代码。这正是其威力所在。
二、async/await使用规则(怎么使用)
2.1、凡是在前面添加了async的函数在执行后都会自动返回一个Promise对象
直接看代码:
async function getusers(){
}
console.log(getusers())
//Promise { undefined }
即使函数什么都没返回,依然打出了Promise对象。
2.2、await必须在async函数里使用,不能单独使用
错误示范:
function getusers2(){
let result=await Promise.resolve("成功");
console.log(result);
}
//await is only valid in async function
正确使用:
async function getusers2(){
let result=await Promise.resolve("成功");
console.log(result);
}
getusers2()
//成功
2.3、await后面需要跟Promise对象,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数。
function demo(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve("成功demo")
}, 1000);
})
}
async function getusers3(){
let result=await demo();
console.log(result);
}
getusers3()
//1秒后输出:成功demo
关于await后面需要跟Promise对象,不然就没有意义的解释:
1.如果await后面是 promise对象会造成异步函数停止执行并且等待 promise 的解决。上面的代码已经解释。
2.如果await后面是 正常的表达式则会被转换成一个 立即 resolve 的 Promise。
async function getusers3_2(){
let result=await 123;
console.log(result);
}
getusers3_2()
//立即输出123
2.4、async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变。也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。await会在内部阻塞代码的执行。
const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function fn(){
console.time();
await delay(1000);
await delay(2000);
await delay(3000);
console.timeEnd();
return "done";
}
fn().then(time=>console.log(time));
//default: 6007.805ms
//done
这样就让代码变成了同步的代码,但运行速度上也损失了,得不偿失呀,换一种写法,当然写法不止这一种:
const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function fn2(){
console.time();
let delay1=delay(1000);
let delay2=delay(2000);
let delay3=delay(3000);
await delay1;
await delay2;
await delay3;
console.timeEnd();
return "done";
}
fn2().then(time=>console.log(time));
//default: 3002.155ms
//done
三、async 相较于 Promise 的优势
3.1相比于Promise,能更好的处理then链
//基础代码
function take(n){
return new Promise(resolve=>{
setTimeout(() => {
resolve(n+1000);
}, n);
})
}
function step1(n){
console.log("step1:"+n);
return take(n);
}
function step2(n){
console.log("step2:"+n);
return take(n);
}
function step3(n){
console.log("step3:"+n);
return take(n);
}
使用Promise方式:
function todoPromise(){
console.log("todoPromise");
const time1=1000;
step1(time1)
.then(time2=>step2(time2))
.then(time3=>step3(time3))
.then(result=>{
console.log(result);
})
}
todoPromise()
// step1:1000
// step2:2000
// step3:3000
// 4000
使用async/await方式:
async function todoasync(){
console.log("todoasync");
const time1=1000;
const time2=await step1(time1);
const time3=await step2(time2);
const result=await step3(time3)
console.log(result);
}
todoasync()
// step1:1000
// step2:2000
// step3:3000
// 4000
其结果是一样的,但是async的代码看上去是非常清晰的,几乎和同步代码一样。当然使用什么也是视业务场景来决定的。