[译]await VS return VS return await

原文地址:await vs return vs return await 做者:Jake Archibaldgit

当编写异步函数的时候,await,return,return await三者之间有一些区别,从中选取正确的方式是很重要的。 咱们从下面这个异步函数开始:github

async function waitAndMaybeReject(){
    // 等待1秒钟
    await new Promise(resolve => setTimeout(resolve, 1000));
    // 抛一枚硬币
    const isHeads = Boolean(Math.round(Math.random()));
    if(isHeads) return 'yay';
    throw Error('Boo!');
}
复制代码

上面的函数会等待1秒钟后返回一个promise,而后有50%的机会成功返回yay或者抛出一个error。让咱们用几种稍微不一样的方式使用它。promise

【译者注:若是您想尝试运行下面的代码来验证结果,请建立async函数中使用await来调用foo函数】dom

直接调用

async function foo() {
    try{
        waitAndMaybeReject();
    }catch(e){
        return 'caught';
    }
}
复制代码

在此处,若是调用了foo,返回的promise的状态始终都是resolved,值也永远是undefined,并且没有等待。 因为咱们没有await,或者return waitAndMaybeReject()的结果,因此咱们没法对它作出任何反应。像这样的代码一般是错误的。异步

Awaiting

async function foo(){
    try{
        await waitAndMaybeReject();
    }catch(e){
        return 'caught';
    }
}
复制代码

在此处,若是调用了foo,返回的promise将始终等待1秒钟,而后结果要么状态为resolved,值为undefined,要么状态为resolved,值为"caught" 由于咱们等待了waitAndMaybeReject()的返回值,因此它的rejection会被返回而且被抛出(throw),catch的代码块就会执行。但不管如何,若是waitAndMaybeReject()没有报错而是顺利执行,咱们依旧没法对它的返回值作任何事情。async

Returning

async function foo() {
    try {
        return waitAndMaybeReject();
    }
    catch (e) {
        return 'caught';
    }
}
复制代码

在此处,若是调用了foo,返回的promise将始终等待1秒钟,而后结果要么是状态为resolved,值为"yaa",要么是状态是reject,抛出错误Error('Boo!') 经过return waitAndMaybeReject()这行代码,咱们直接传递了它的返回结果,因此咱们的catch代码块永远不会执行。函数

Return-awaiting

若是你想在try代码块中获得带有正确返回值的resolved状态,在catch中捕获异常,那么正确的选择就是return awaitui

async function foo() {
    try {
        return await waitAndMaybeReject();
    }
    catch (e) {
        return 'caught';
    }
}
复制代码

在此处,若是调用foo,返回的promise将始终等待1秒钟,而后结果要么是状态为resolved,值为"yay",要么是状态为resolved,值为"caught" 由于咱们等待了waitAndMaybeReject()的结果,因此它的异常rejecttion会被返回而且被抛出(throw),catch的代码块就会执行。若是waitAndMaybeReject()顺利执行没有报错,就返它的结果。spa

若是对上面的内容仍是觉着困惑,那么将代码拆分红两个步骤来看可能会比较好理解:eslint

async function foo() {
  try {
    // 等待 waitAndMaybeReject() 的结果来解决,
    // 而且将 fullfill 的值赋给 fullfilledValue:
    const fulfilledValue = await waitAndMaybeReject();
    // 若是 waitAndMaybeReject() reject了,
    // 咱们的代码就会抛出异常,而且进入 catch 代码块的逻辑。
    // 不然,这里的代码就会继续运行下面的语句:
    return fulfilledValue;
  }
  catch (e) {
    return 'caught';
  }
}
复制代码

Note: 在try/catch以外的代码块中执行return await是多余的(如前所述,直接return便可),甚至Eslint还专门有规则来检测这种场景,可是在try/catch代码块以内,Eslint就容许这种操做。

相关文章
相关标签/搜索