原文地址:await vs return vs return await
作者:Jake Archibald

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


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。让我们用几种稍微不同的方式使用它。

直接调用


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()没有报错而是顺利执行,我们依旧无法对它的返回值做任何事情。

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 await


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

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

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


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就允许这种操作。

来源:https://segmentfault.com/a/1190000017120123

[译]await VS return VS return await的更多相关文章

  1. 关于async 中return 和 return await 的差异

    小七平时在使用ES2017的 async功能经常会有如下: const bluebird = require('bluebird'); async function doSomething() { a ...

  2. 【译】Async/Await(三)——Aysnc/Await模式

    原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...

  3. java中 try return finally return

    finally块里面的代码一般都是会执行的,除非执行 System.exit(int),停止虚拟机,断电. 1.若try代码块里面有return ,假设要return 的值 是A,A为基本类型或者被f ...

  4. java中 try return finally return(转)

    finally块里面的代码一般都是会执行的,除非执行 System.exit(int),停止虚拟机,断电. 1.若try代码块里面有return ,假设要return 的值 是A,A为基本类型或者被f ...

  5. JavaScript 中 return,return true,return false

    1.return: ①return + 表达式,调用函数,并返回表达式的值 ②return,终止函数 ③当代码执行到return语句时,函数返回一个结果就结束运行了,return后面的语句根本不会执行 ...

  6. js里面return 和 return false的区别

    js里面return 和 return false的区别 1.都可以终止执行当前方法: 2.如果方法A调用了方法B,则在方法A中使用return可以终止程序,但是在方法B中使用return则终止执行B ...

  7. java中,return和return null有什么区别吗?

    java中,return和return null有什么区别吗? 最大的区别:return;方法的返回值必须是void!return null;方法的返回值必须不是 原始数据类型(封装类除过)和void ...

  8. js中return;return true return false 的区别

    return 定义: return 语句会 终止函数的执行 并 返回函数的值. 注意这两个: 1.终止函数的执行 2.返回函数的值 返回函数的值这里就不过多叙述了,就是 return 变量 先看下面的 ...

  9. js中的return,return true,return false小结

    return  函数执行到这句时会终结,并返回调用函数,而且把表达式的值作为函数的结果返回 return false 可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转 ...

随机推荐

  1. Bootstrap告警框(alert)实现弹出效果和短暂消失后上浮消失

    最近用到bootstrap的告警框时发现只有html的说明,就自己写了一个弹出告警框和弹出短暂显示后上浮消失的告警框. 直接上JS代码了,可以copy过去直接用(使用bootstrap的UI框架的情况 ...

  2. 微信小程序——导航栏组件

    组件内属性详解   属性 类型 默认值 必填 说明 nav-postion String relative 否 导航栏(包含导航栏以及状态栏)的position,可取值relative.fixed.a ...

  3. 设计模式C++模板(Template)模式

    设计模式C++描述----02.模板(Template)模式(转载) 一. 问题 在面向对象系统的分析与设计过程中经常会遇到这样一种情况:对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现, ...

  4. WPF新手快速入门系列 3.MVVM

    [概要] 这一章主要讲述,讲述MVVM模式和用法. 如有学习过程中想交流学习.疑惑解答可以来此QQ群交流:580749909.(所有涉及到的源码都上传到了群文件里) 希望加群的人提问时尽量想清楚自己的 ...

  5. OC基础--字符串

    前言 做iOS开发有3年了,从当初的小白到现在,断断续续看过很多资料,之前也写过一些博文来记录,但是感觉知识点都比较凌乱.所以最近准备抽时间把iOS开发的相关知识进行一个梳理,主要分为OC基础.UI控 ...

  6. Codeforces1312D Count the Arrays 组合数学

    题意 给你\(n\)和\(m\),问满足以下条件的数列的个数: 数列长度为\(n\) 数列值域范围为\(\left[1,m\right]\) 数列有且仅有一对相等的数 数列是单峰数列(先严格递增后严格 ...

  7. 关于ASP.NET MVC的权限认证的一些总结

    最近在学ASP.NET MVC的权限认证的一些东西,上网搜索了一阵,发现网上的方法大多数是以下几类: 一.FormsAuthentication.SetAuthCookie(admin.Name, f ...

  8. 递归方式---通过子级id,获取子级和父级Name

    #region 递归--返回 父级|子级 名称 #region --返回 父级|子级 名称 public string RetrurnTypeNames(string TypeId) { String ...

  9. “未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决方案

    不论是连接Access数据库或是SQL Server数据库,"未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序."这个问题从Of ...

  10. pycharm写的代码提交到git上,提示需要merge失败时解决办法

    当遇到pycharm代码提交需要合并报错时 原因:pycharm目录和git中目录冲突了 解决办法:1.先在git仓库中创建一个文件夹,比如day1 2.然后在pycharm中update一下,可以看 ...