Open xingbofeng opened 7 years ago
表示很烦一堆堆 catch
@xuexb 其实在后面跟同事讨论异常捕获的问题时,可以通过Promise.then
方法第二个参数捕获异常,这样就没有一堆堆的catch
了。
但是这种方式在then
写异常捕获,不是我们最常见的那种写法,不具有较好的代码可读性。
回调里面如何用await?
function a(){
$.get(url,data,function(data){
return data;
},'json');
}
// 用法: async function(){ var a = await a(); // 这样子调用有没有错? }
try catch 我们这边统一包装成 return [err, results] 类似与Go语言的写法 来处理错误 大家讨论一下是否可行呢。
感觉return [err,results]的方式进行错误处理比较好啊,不然的话单纯使用try ... catch ... 语句块无法为后续代码指明之前的执行结果是否有误,需要加入额外变量去完成。
用了一下 async / await,发现只有在 Promise 嵌套的时候,写起来比较好看(大多数介绍写法优势的也是提供这样的案例 ...),如果是单个的 Promise 处理(很多时候是这样),好像并没有 req.then(data => {}).catch(err => {}) 的写法更直观 ...
感谢博主转发哈!也欢迎继续关注Fundebug博客~
之前阅读过一篇文章《Async/Await替代Promise的6个理由》,现在async / await语法已经处于Stage3阶段。
兼容性
Node.js 7.6
版本后,async / await
语法已经被Node.js
支持,如Koa2
已经抛弃generator/yield语法,拥抱async / await
语法。Babel
让我们随心所欲地使用最新的Ecmascript
语法。从业务说起
单从我个人来讲,是不太喜欢使用这样的最新语法的。一直以来写代码还是拥抱
Promise
为主。但自从用上了async / await
语法后好像就会对这种语法产生依赖感(看起来就像是同步阻塞的代码一样,还不用像generator
语法那样手动释放,或使用co
那样的流程控制库)看下面这些常见的业务场景:
我们如果使用
Promise
语法:虽然使用
Promise
,catch
只能捕获到最近一次Promise.then
的错误,但是实际上现在,其实可以这么捕获每次的错误!不要忘记
Promise.then
的第二个参数:现在有一个问题,服务端可能会校验用户登录态,或参数是否正确等情况。如果用户登录态失效,会在第一个
ajax
请求中,仍会走success
回调,并不会抛出错误,此时还是得去手动修改requestSubmit
函数。此外,
Promise.catch
方法只会捕获最近一次错误,那这个错误究竟在哪里抛出,其实并不得而知。如:
但是注意:原文其实说得不全,我们这么捕获
Promise
的错误是可以的:如果把上述业务场景改为
async / await
语法:无论从异常捕获方面还是从代码可读性方面,都会感觉更胜一筹。
优势
这里其实大多数就是捡取那篇文章:
简洁
使用
async / await
明显节约了不少代码。我们不需要写.then
,不需要写匿名函数处理Promise
的resolve
值,也不需要定义多余的data变量,还避免了嵌套代码。这些小的优点会迅速累计起来,这在之后的代码示例中会更加明显。错误处理
async / await
让try / catch
可以同时处理同步和异步错误。在下面的Promise
示例中,try / catch
不能处理JSON.parse
的错误,因为它在Promise
中。我们需要使用.catch
,这样错误处理代码非常冗余。并且,在我们的实际生产代码会更加复杂。使用
async / await
的话,catch
能处理JSON.parse
错误:条件语句
这一点在上边也说了:
下面示例中,需要获取数据,然后根据返回数据决定是直接返回,还是继续获取更多的数据。
这些代码看着就头痛。嵌套(6层),括号,
return
语句很容易让人感到迷茫,而它们只是需要将最终结果传递到最外层的Promise
。上面的代码使用
async / await
编写可以大大地提高可读性:中间值
你很可能遇到过这样的场景,调用promise1,使用promise1返回的结果去调用promise2,然后使用两者的结果去调用promise3。你的代码很可能是这样的:
如果
promise3
不需要value1
,可以很简单地将promise
嵌套铺平。如果你忍受不了嵌套,你可以将value 1 & 2
放进Promise.all
来避免深层嵌套:错误栈
这里可见上边真实的业务例子。
调试
async/await
能够使得代码调试更简单。2个理由使得调试Promise
变得非常痛苦:.then
代码块中设置断点,使用Step Over
快捷键,调试器不会跳到下一个.then
,因为它只会跳过异步代码。使用await / async
时,你不再需要那么多箭头函数,这样你就可以像调试同步代码一样跳过await
语句。