前端前端好文

async和await

2020-01-28  本文已影响0人  agamgn

前言

 异步操作一直是Javascript中重要的一部分,从回调到Promise再到async/await,异步操作是越来越简单,现在来看看async和await的用处。

一、async/await是什么

 async/await是Javascript中对于异步操作的解决方案,被称为终极解决方案,他是 Generator 函数的语法糖,关于Generator 函数参考Generator使用。其有以下特点:

二、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的代码看上去是非常清晰的,几乎和同步代码一样。当然使用什么也是视业务场景来决定的。

总结

async
本节代码

上一篇下一篇

猜你喜欢

热点阅读