小七平时在使用ES2017的 async功能经常会有如下:

const bluebird = require('bluebird');

async function doSomething() {
await bluebird.delay(1000);
throw new Error('ttt');
} (async function() {
return doSomething();// 关注点
})()
.then(function() {
console.log('ok');
})
.catch(function(err) {
console.error('fail');
});

小七在调用doSomething的时候直接使用 `return doSomething()` ,而不是用 `return await doSomething()`。

因为它们的执行和结果都是一样的。在大部分情况下,这种方式是正确的,而且代码也比较简洁。

但事实上在执行的时候是有些差异的,我们看下下面的例子。

(async function() {
try {
return doSomething();// 关注点,这里我们省略了await 产生了更我们设想不太一样的结果
} catch (err) {
console.log('do something ignore');
}
})()
.then(function() {
console.log('ok');
})
.catch(function(err) {
console.error('fail');
});
//输出 :fail

小七这里原本的设想是 在调用doSomething的时候,如果有什么错误的话,忽略错误,正常返回。

但是结果确实抛出了错误,被最后面的catch捕获。输出了fail。

于是调整了下代码:

const bluebird = require('bluebird');

async function doSomething() {
await bluebird.delay(1000);
throw new Error('ttt');
} (async function() {
try {
return await doSomething();// 关注点,这里恢复了省略掉的 await
} catch (err) {
console.log('do something ignore');
}
})()
.then(function() {
console.log('ok');
})
.catch(function(err) {
console.error('fail');
});
//输出 :
//do something ignore
//ok

把 await 恢复回来就正常了。

这里主要的原因就在于小七对async语法糖原理的误解,小七以为在async函数中使用return的时候和return await是一样的,是因为return 隐含了await的功能。然而并非如此,async中的return 只是简单的返回一个promise,所以return 在使用的时候并没有任何抛错,try catch 自然就没法获得该错误。而返回的promise被后面的.catch方法捕获到错误。

而如果使用  return await doSomething() 的时候,等价于 先await了doSomething返回的promise,如果有reject,则会直接传给cacth block 处理。

总结,async函数中的return 并没有黑魔法,在大部分情况下也不需要黑魔法,因为async方法的结果也是一个promise,所以返回一个promise是等价的。

但我们还是要理解它的实现原理。

因为在async 中 try catch 语法糖的原理是处理同步抛出的错误和await产生的reject,所以,我们不能省略掉await的调用。

关于async 中return 和 return await 的差异的更多相关文章

  1. [译]await VS return VS return await

    原文地址:await vs return vs return await作者:Jake Archibald 当编写异步函数的时候,await,return,return await三者之间有一些区别, ...

  2. jquery中ajax用return来返回值无效

    jquery中,ajax返回值,有三种写法,只有其中一种是成功的 /** * async:false,同步调用 * 返回1:2 * 失败 * 分析:ajax内部是一个或多个定义的函数,ajax中ret ...

  3. 可惜Java中没有yield return

    项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...

  4. java中 try return finally return

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

  5. java中finally和return的执行顺序

    注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有re ...

  6. C#中的yield return与Unity中的Coroutine(协程)(上)

    C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...

  7. for循环中使用了return

    for循环中使用了return,导致没有循环完毕就结束了整个方法的执行.

  8. (转)解析php中die(),exit(),return的区别

    本篇文章是对php中die(),exit(),return的区别进行了详细的分析介绍,需要的朋友参考下     die()停止程序运行,输出内容exit是停止程序运行,不输出内容return是返回值d ...

  9. java中 try return finally return(转)

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

随机推荐

  1. 洲阁筛 & min_25筛学习笔记

    洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...

  2. Java语言之循环基础;各个语句的区别

    FOR: WHILE DO WHILE break 与 continue的区别 break直接中断语句跳出循环,continue跳出当前循环,后面会继续执行

  3. Nginx1.14.0+ModSecurity实现简单的WAF

    一.编译安装Nginx 1.安装依赖环境 $ yum -y install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel ...

  4. druid 连接池加密算法

    package juint; import com.alibaba.druid.filter.config.ConfigTools; public class DruidTest { public s ...

  5. CentOS7.4用yum安装并配置MySQL5.7

    1.配置YUM源 下载MySQL源安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 安装MySQ ...

  6. Windows7下Jupyter Notebook使用入门

    目录 一.Jupyter简介 二.Jupyter安装 2.1 python 3安装 2.2 Jupyter 安装 三.Jupyter使用示例 四.Jupyter常用命令 五.其他说明 一.Jupyte ...

  7. pytest--fixture参数化的实现方式和执行顺序

    之前看到fixture函数可以通过添加,params参数来实现参数化,后续看到了悠悠 的博客,可以通过@pytest.mark.parametrize来实现,现在做一个总结 实现方式一 通过param ...

  8. Qt中隐藏滚动条重新实现鼠标滚轮事件wheelEvent

    delta()已经被弃用了,QT5中用的是angleDelta(),计算的时候取angleDelta().y()值. #重载方法wheelEvent(self,event),即滚轮事件方法 #---- ...

  9. 雷林鹏分享:YAF路由问题

    这2天休年假,在家宅着学习研究了YAF框架,用YAF做过APP接口的项目,但是没有用来做过WEB方面的应用.趁着这2天在家想把博客用YAF进行一下改版,目的也想进一步学习一下YAF. 在这过程中遇到不 ...

  10. 记录Sql2012附加Sql2008的数据库出错的解决方案

    只需要对要附加的数据文件[右键]->[属性]->[安全]->(选择“Authenticated Users”用户)[编辑]->让“Authenticated Users”用户具 ...