小七平时在使用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的调用。

最新文章

  1. 多行文本溢出显示省略号(…) text-overflow: ellipsis
  2. jQuery data
  3. 第五篇:白话tornado源码之褪去模板的外衣
  4. 使用 Eclipse 调试 Java 程序的技巧
  5. git 教程(12)--分支管理
  6. 引入HBase依赖包带来的麻烦
  7. 图解SQL的各种连接join[转]
  8. 【DDD-Apwork框架】事件总线和事件聚合器
  9. POJ2418——Hardwood Species(map映射)
  10. Android开发之ListView-SimpleAdapter的使用
  11. Google市场推广统计
  12. QTableWidget表格合并若干问题及解决方法
  13. 27.编写一个Animal类,具有属性:种类;具有功能:吃、睡。定义其子类Fish 和Dog,定义主类E,在其main方法中分别创建其对象并测试对象的特性。
  14. tomcat连接数设置
  15. Linux下Nginx、PHP、MySQL、Redis开机自启动设置
  16. 截屏 iOS
  17. JS数组的基本操作方法
  18. Sudoku POJ - 3076
  19. win10企业版2016长期服务版本激活
  20. Netty学习路线总结

热门文章

  1. springboot使用validation 插件做数据校验
  2. Bugku-CTF之过狗一句话(送给大家一个过狗一句话)
  3. 关于php下的ajax赋值传值的调试
  4. CF666E Forensic Examination
  5. POJ1192最优连通子串----树形dp
  6. .NET Core Agent
  7. TP5创建动态数据表
  8. 承接VR外包,虚拟现实外包,北京正规公司
  9. Hybrid App 开发模式
  10. ArcGIS Pro开发Web3D应用(1)——环境搭建与初始实例