关于async 中return 和 return await 的差异
小七平时在使用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 的差异的更多相关文章
- [译]await VS return VS return await
原文地址:await vs return vs return await作者:Jake Archibald 当编写异步函数的时候,await,return,return await三者之间有一些区别, ...
- jquery中ajax用return来返回值无效
jquery中,ajax返回值,有三种写法,只有其中一种是成功的 /** * async:false,同步调用 * 返回1:2 * 失败 * 分析:ajax内部是一个或多个定义的函数,ajax中ret ...
- 可惜Java中没有yield return
项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...
- java中 try return finally return
finally块里面的代码一般都是会执行的,除非执行 System.exit(int),停止虚拟机,断电. 1.若try代码块里面有return ,假设要return 的值 是A,A为基本类型或者被f ...
- java中finally和return的执行顺序
注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有re ...
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...
- for循环中使用了return
for循环中使用了return,导致没有循环完毕就结束了整个方法的执行.
- (转)解析php中die(),exit(),return的区别
本篇文章是对php中die(),exit(),return的区别进行了详细的分析介绍,需要的朋友参考下 die()停止程序运行,输出内容exit是停止程序运行,不输出内容return是返回值d ...
- java中 try return finally return(转)
finally块里面的代码一般都是会执行的,除非执行 System.exit(int),停止虚拟机,断电. 1.若try代码块里面有return ,假设要return 的值 是A,A为基本类型或者被f ...
随机推荐
- elasticsearch-mapping字段重要属性
https://blog.csdn.net/gongpulin/article/details/78705205
- line-height各类属性值
line-height支持属性值 1.normal(默认属性) 跟着用户的浏览器走,且与元素字体关联 normal值 = 字体大小/100 2.<number> 使用数值作为行高值.如:l ...
- 快速签发 Let's Encrypt 证书指南
本文仅记录给自己的网站添加"小绿锁"的动手操作过程,不涉及 HTTPS 工作原理等内容的讲解,感兴趣的同学可以参考篇尾的文章自行了解. 简单了解下我的实验环境: 云服务器:Cent ...
- ng/cli uses yarn as the package manager
Switch to working directory Excuting the following command ng config cli.packageManager yarn
- BeanUtils的copyproPerties方法的用法
转自:Hassan Blog的博客 一.简介: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包 ...
- js 延时等待
//延时器,2秒后执行函数 function test(){ alert("aaaa"); } setTimeout(function () { test(); }, ); //或 ...
- 学习笔记71—Python 报错处理集
****************************************************** 如有谬误,请联系指正.转载请注明出处. 联系方式: e-mail: heyi9069@gm ...
- primer3批量设计引物
核心程序调用 Primer3_core,基本用法: primer3_core [ -format_output ] [ -default_version=1|-default_version=2 ] ...
- C语言实验一(1)
#include<stdio.h>int main(){ int a,b,sum; a=123; b=456; sum=a+b; printf("sum is %d\n" ...
- PHP异常和错误
一.PHP的异常和错误 异常:在程序运行中不符合预期的情况及与正常流程不同的情况.一种不正常的情况,就是按照正常逻辑不该出错,但任然出错的情况,这属于逻辑和业务流程的一种中断,而不是语法错误.PHP只 ...