返回承诺对象时使用`Async`关键字

时间:2020-01-18 12:22:47

标签: javascript promise async-await

我正在开发一些Nodejs脚本,并且对JS本身中async关键字的用法有疑问。

例如,假设我有一个函数返回这样的承诺:

function myFunction () {
  ... some job
  return new Promise(async (resolve, reject) => {
    const innerResult = await someHeavyJob();
    ... some job
    resolve(innerResultThatIsManipulated);
  });
}

我可以用另一种方式写它:

async function myFunction () {
  ... some job
  const innerResult = await someHeavyJob();
  ... some job
  return innerResultThatIsManipulated;
}

但是我有一个问题,如果我选择第一个解决方案,那我可以使用async关键字吗?是否建议这样做?例如,如下所示:

async function myFunction () {
  ... some job
  return new Promise(async (resolve, reject) => {
    const innerResult = await someHeavyJob();
    ... some job
    resolve(innerResultThatIsManipulated);
  });
}

要强调这是一个异步方法,并且会在其代码的所有路径中返回promise(不是简单的对象)。

那么,推荐的使用方式是什么?

2 个答案:

答案 0 :(得分:1)

MDN说:

异步函数声明定义了一个异步函数-a 返回AsyncFunction对象的函数。异步功能 通过事件以与其余代码不同的顺序进行操作 循环中,返回一个隐含的承诺作为结果。但是语法和 使用异步功能的代码结构看起来像标准 同步功能

这样做:

async function myFunction () {
  return new Promise(async (resolve, reject) => {
    const innerResult = await someHeavyJob();
    resolve(innerResult);
  });
}

您返回的是隐含的诺言,该诺言返回了诺言。您问过,让代码更具可读性是否会是一种有趣的方法,我相信它会使您混淆不清。

(甚至不谈论在async函数内部的promise中的异步函数,该函数实际上仅包含那个仅包含该async函数的promise,我谈论的第一个不是最后一个,我的意思是第二个,您遵循了吗?编辑:您实际上已经编辑了该代码段,仅用于示例)

MDN添加:

async / await的目的是简化同步使用Promise

在我的理解中,异步功能是对Promise的替代,而不是每个说法的扩展。因此,按照您的建议将两者结合起来似乎是不明智的。

答案 1 :(得分:1)

在所有显示的示例中,只有第二个是正确的。其背后的原因是Promise是一个构造函数(因此您将其与new一起使用)采用了常规函数,而不是另一个Promise作为参数。

示例1

解释器将您的第一个示例翻译成(理论上)这样的内容:

new Promise( new Promise((resolve, reject) => { ... }))

这不是您想要的,也被认为是反模式。相反,您需要这样做:

new Promise((resolve, reject) => { ... })

此外,似乎您已经具有一个产生someHeavyJob的函数(Promise)。为什么要将它包装在另一个Promise中?只需使用.then返回的Promise的{​​{1}}方法就可以转换给您的内容。

最后,您会得到类似的东西:

someHeavyJob

示例3

出于相同的原因,从技术和逻辑角度讲,第三个示例都不正确,第三个示例不正确。

一般经验法则

请勿将function myFunction() { // ... some job return someHeavyJob(). then( result => { // ... some job with result }) } async(仅)用作传达某些功能本质上与其他人(或您将来的自己)异步的方式。这两个关键字都会对您编写的代码产生隐式影响,并使其行为有所不同。

尝试同时遵守这两种约定(使用await / Promise使用async )。仅在确实需要时将它们混合。

我个人而言,我尝试坚持使用await而不是Promise / async,因为它们经常使人们感到烦恼,而且-对我来说-他们俩都没有带来太多好处除了使代码“看起来更好”。但是,那只是我个人的看法。