小七平时在使用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. linux服务基础(三)之Httpd2.4配置

    httpd-2.4 新特性: . MPM支持运行DSO机制,以模块形式按需加载 . 支持event MPM . 支持异步读写 . 支持每模块及每个目录分别使用各自的日志级别 . 每请求配置 <I ...

  2. js中call()的用法

    A.call(B,x,y) 1`改变函数A的this指向,使之指向B; 2` 把A函数放到B中运行,x和y是A函数的参数. //父类 Person     function Person() {   ...

  3. 在多机器上远程执行JMeter

    安装完jmeter之后直接执行%InstallDir%\apache-jmeter-3.2\bin\JMeter.bat可以启动UI界面,可以编辑或者执行TestPlan等,默认情况下,用例是在本机执 ...

  4. ELK6.6.0+filebeat6.6.0部署

    elastic不能用root用户去启动,否则会报错,所以创建elastic用户ES集群部署 1.创建elastic用户 $ useradd elastic $ passwd elastic 2..部署 ...

  5. error LNK1169 找到一个或多个多重定义的符号的解决方法

    问题描述如下: 有 三个源文件,A.h.B.cpp.C.cpp. A.h是头文件,其中声明了三个变量a1.a2. a3. B.cpp是A.h中所声明的类的实现源代码,C.cpp是主程序文件.B.cpp ...

  6. Vue小项目二手书商城:(一)准备工作、组件和路由

    本项目基于vue2.5.2,与低版本部分不同之处会在(五)参考资料中提出 完整程序:https://github.com/M-M-Monica/bukesi 实现内容: 资源准备(mock数据) 组件 ...

  7. Oracle配置SQL空间操作要点说明

    前面配置PL/SQL直接通过SQL查询SDE空间数据库,网上已有诸多示例, 常见问题如下: ORA-06520: PL/SQL: 加载外部库时出错ORA-06522: Unable to load D ...

  8. Oracle之数组

    记忆力不好,提供样例套路: 固定长度数组: declare type t_test ) ); test t_test := t_test('a', 'b', 'c', 'd', 'e'); begin ...

  9. guxh的python笔记十一:异常处理

    1,抓错方法 name = [0, 1, 2] try: name[3] except IndexError as exc: # 抓单个错误,打印错误信息e print(exc) except (In ...

  10. java,sort的数组降序

    1.Array.sort(数组,起始位置,结束位置).这个是升序排序. 2.关于数组的降序实现如下: 利用Collections.reverseOrder()方法: import java.util. ...