async 与await 解析

Posted aidixie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了async 与await 解析相关的知识,希望对你有一定的参考价值。

  async与await 是promise的语法糖,是把promise的异步写成像同步的写法。

语法:

  1、async 后面接一个自定义函数

  2、await 只能放在async 后面的函数里,且await后面接一个会 ruturn new Promise 的函数,等到异步完成就继续往下执行

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 10)
        setTimeout(()=>{
            resolve(sino)
        },1000)
    })
};
async function test(){
    let n =await hello()
    console.log(n)
};
test();

上面这段代码async中使await hello()先执行,等到一秒后执行完再把得到的结果赋值给左边的n,也就是说test函数需要一秒钟才执行完成,所以test函数是异步的,因此前面必须写async

  在一个async的函数中多次使用await实现多次回调

function a(num){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve(num+num)
        },1000)
    })
}
function b(num){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve(num*num)
        },1000)
    })
}
async function test(){
    let n =await a(8)
    console.log(n); // 16
    let m= await b(n)
    console.log(m) // 256
}
test();

  上面的例子都是走的resolve成功,那么如果走reject会怎样呢:会出现报错

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 10)
        setTimeout(()=>{
            reject(sino)
        },1000)
    })
};
async function test(){
    let n =await hello()
    console.log(n)
};
test();

  技术图片

  那么应该如何处理promise的reject事件,采用try{}catch(){}

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = 10;
        setTimeout(()=>{
            reject(sino)
        },1000)
    })
};
async function test(){
    try{
        let n =await hello()
        console.log(n)
    }catch(err){
        console.log(err); // 10
    }
};
test();

  这样做就处理reject函数的错误,但是又与async与await简写代码、异步像同步一样的初衷相不符;

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = 10;
        setTimeout(()=>{
            reject(sino)
        },1000)
    })
};
async function test(){
        let n =await hello().then(resolve=>res).catch(reject=>rej);
        console.log(n) // 10
};
test();
//上面那种方法是有一定问题的,我们无法判断返回值

  我们可以通过在改变then和catch里的返回值,在里面添加特征符号。

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = 10;
        setTimeout(()=>{
            reject(sino)
        },1000)
    })
};
async function test(){
        let n =await hello().then(res=>["res",res]).catch(rej=>["rej",rej]);
        console.log(n) // ["rej",10]
};
test();

  继续优化 

function hello(){
    return new Promise((resolve, reject)=>{
        let sino = 10;
        setTimeout(()=>{
            reject(sino)
        },1000)
    })
};
function awaitWraper(promiseFun){
    return promiseFun().then(res=>["resolve",res]).catch(rej=>["reject",rej])
};
console.log(awaitWraper(hello)) // Promise {<pending>} 仍然是promise,这就是仍可以await原因
async function test(){
        let n =await awaitWraper(hello);
        console.log(n) // ["reject",10] 这就说明reject错误,输出10
};
test();

以上是关于async 与await 解析的主要内容,如果未能解决你的问题,请参考以下文章

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

flutter async和await原理解析

是否可以在没有 async/await 的情况下从 Promise 返回已解析的值?

promise与async和await的区别

async 与 await 线程调用顺序