摘要:由于我们没有,或者的结果,所以我们无法对它做出任何反应。因为我们等待了的返回值,所以它的会被返回并且被抛出,的代码块就会执行。但无论如何,如果没有报错而是顺利执行,我们依旧无法对它的返回值做任何事情。
原文地址:await vs return vs return await
作者:Jake Archibald
当编写异步函数的时候,await,return,return await三者之间有一些区别,从中选取正确的方式是很重要的。
我们从下面这个异步函数开始:
async function waitAndMaybeReject(){ // 等待1秒钟 await new Promise(resolve => setTimeout(resolve, 1000)); // 抛一枚硬币 const isHeads = Boolean(Math.round(Math.random())); if(isHeads) return "yay"; throw Error("Boo!"); }
上面的函数会等待1秒钟后返回一个promise,然后有50%的机会成功返回yay或者抛出一个error。让我们用几种稍微不同的方式使用它。
直接调用async function foo() { try{ waitAndMaybeReject(); }catch(e){ return "caught"; } }
在此处,如果调用了foo,返回的promise的状态始终都是resolved,值也永远是undefined,而且没有等待。
由于我们没有await,或者return waitAndMaybeReject()的结果,所以我们无法对它做出任何反应。像这样的代码通常是错误的。
async function foo(){ try{ await waitAndMaybeReject(); }catch(e){ return "caught"; } }
在此处,如果调用了foo,返回的promise将始终等待1秒钟,然后结果要么状态为resolved,值为undefined,要么状态为resolved,值为"caught"。
因为我们等待了waitAndMaybeReject()的返回值,所以它的rejection会被返回并且被抛出(throw),catch的代码块就会执行。但无论如何,如果waitAndMaybeReject()没有报错而是顺利执行,我们依旧无法对它的返回值做任何事情。
async function foo() { try { return waitAndMaybeReject(); } catch (e) { return "caught"; } }
在此处,如果调用了foo,返回的promise将始终等待1秒钟,然后结果要么是状态为resolved,值为"yaa",要么是状态是reject,抛出错误Error("Boo!")。
通过return waitAndMaybeReject()这行代码,我们直接传递了它的返回结果,所以我们的catch代码块永远不会执行。
如果你想在try代码块中得到带有正确返回值的resolved状态,在catch中捕获异常,那么正确的选择就是return await。
async function foo() { try { return await waitAndMaybeReject(); } catch (e) { return "caught"; } }
在此处,如果调用foo,返回的promise将始终等待1秒钟,然后结果要么是状态为resolved,值为"yay",要么是状态为resolved,值为"caught"
因为我们等待了waitAndMaybeReject()的结果,所以它的异常rejecttion会被返回并且被抛出(throw),catch的代码块就会执行。如果waitAndMaybeReject()顺利执行没有报错,就返它的结果。
如果对上面的内容还是觉着困惑,那么将代码拆分成两个步骤来看可能会比较好理解:
async function foo() { try { // 等待 waitAndMaybeReject() 的结果来解决, // 并且将 fullfill 的值赋给 fullfilledValue: const fulfilledValue = await waitAndMaybeReject(); // 如果 waitAndMaybeReject() reject了, // 我们的代码就会抛出异常,并且进入 catch 代码块的逻辑。 // 否则,这里的代码就会继续运行下面的语句: return fulfilledValue; } catch (e) { return "caught"; } }
Note: 在try/catch之外的代码块中执行return await是多余的(如前所述,直接return即可),甚至Eslint还专门有规则来检测这种场景,但是在try/catch代码块之内,Eslint就允许这种操作。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/99336.html
摘要:异步流程管理说白了就是为了解决回调地狱的问题。对象代表一个异步操作,有三种状态进行中已成功和已失败。如果改变已经发生了,你再对对象添加回调函数,也会立即得到这个结果。执行函数后返回的是一个遍历器对象,可以依次遍历函数内部的每一个状态。 javascript -- 深度解析异步解决方案 高级语言层出不穷, 然而唯 js 鹤立鸡群, 这要说道js的设计理念, js天生为异步而生, 正如布道...
摘要:本文讨论地址阅读时间大概分钟和有很多容易被忽视的不同之处。首先定义一个异步函数等待秒函数等待秒钟,然后有一半的概率返回,一半的概率抛出异常。这个是最符合我们预期的写法。 dev-reading/fe 是一个阅读、导读、速读的 repo,不要依赖于 dev-reading/fe 学习知识。本 repo 只是一个快速了解文章内容的工具,并不提供全文解读和翻译。你可以通过本平台快速了解文章里...
摘要:对于,除非使用箭头函数,它的回调函数的将会变化。使用测试下面的代码,结果如下打印打印要点使用的规则要求所有回调函数必须使用箭头函数。 译者按: JS 骚操作。 原文:For vs forEach() vs for/in vs for/of in JavaScript 译者: Fundebug 本文采用意译,版权归原作者所有 我们有多种方法来遍历 JavaScript 的数组或者...
摘要:的科学定义是或者,它的标志性原语是。能解决一类对语言的实现来说特别无力的状态机模型流程即状态。容易实现是需要和的一个重要原因。 前面写了一篇,写的很粗,这篇讲讲一些细节。实际上Fiber/Coroutine vs Async/Await之争不是一个简单的continuation如何实现的问题,而是两个完全不同的problem和solution domain。 Event Model 我...
摘要:如果是你是高级或者初级开发人员,了解它的基本概念非常重要。由于是基本类型,因此的值等于的值,并且可以认为此时与完全不同。展开运算符可用于提取数组的各个元素。函数本身返回从数组中删除的项。如果未指定结束位置,则返回数组的其余部分。 译者:前端小智 原文:hackernoon.com/12-javascri… JavaScript 是一种复杂的语言。如果是你是高级或者初级 JavaScript...
阅读 2830·2021-09-10 10:50
阅读 2192·2019-08-29 16:06
阅读 3194·2019-08-29 11:02
阅读 1093·2019-08-26 14:04
阅读 2803·2019-08-26 13:24
阅读 2300·2019-08-26 12:16
阅读 550·2019-08-26 10:29
阅读 3094·2019-08-23 18:33