【问题标题】:Declare existing functions as async?将现有函数声明为异步?
【发布时间】:2018-06-03 07:54:47
【问题描述】:

我使用一个名为 setConf 的函数进行测试。有时候如果我可以用它来启动一个promise链真的很方便,有时候我只需要它来返回值。

是否可以将现有函数声明为异步?我想做但不起作用的是:

const setConf = (conf) => {
  mainConf = Object.assign(mainConf , conf)
  return mainConf 
}

module.exports.asyncSetConf = async setConf
module.exports.setConf = setConf

这是我目前拥有的

exports.asyncSetConf = async (conf) => {
  mainConf = Object.assign(mainConf , conf)
  return mainConf 
}

exports.setConf = (conf) => {
  mainConf = Object.assign(mainConf , conf)
  return mainConf 
}

代码是一样的,不能重构似乎有点傻

【问题讨论】:

  • 将同步执行的函数设为异步函数没有任何价值。但是,您可以通过创建一个在下一次报价时调用该函数的新函数来做到这一点。
  • @KevinB 我认为这只是一个例子。我认为异步的用例是隐含的
  • afaik 您无法将现有函数转换为异步函数。但没有什么能阻止您创建新功能
  • “是否可以将现有函数声明为异步函数?” 不可以。异步函数是返回承诺的函数。如果你需要一个承诺,你可以简单地做Promise.resolve(someExistingFunction())。如果你想使用await,你已经可以这样做了:await someExistingFunction()(不管someExistingFunction返回什么。
  • 如果你想用它开始一个承诺链,那么就这样做:Promise.resolve(setConf(...)).then(...)。不需要async 版本。

标签: javascript ecmascript-6 async-await


【解决方案1】:

首先,使用 async 关键字声明的函数返回一个承诺。所以你要么希望你的函数返回一个承诺,要么你不希望。没有像使用 async 关键字声明的函数这样的东西,它有时会返回一个承诺,有时不会。

其次,如果您的函数中没有异步代码,那么将同步操作包装在异步接口中通常会使事情变得更复杂,而不是更简单,因此通常没有理由这样做。

第三,如果你只是想有时使用setConf() 来启动一个承诺链,你可以简单地用Promise.resolve() 包装它:

Promise.resolve(setConf(...)).then(f).then(g).catch(...)

当然,您也不一定需要这样做,因为如果 f() 是异步的并返回一个承诺,您可以这样做:

f(setConfg(...)).then(g).catch(...)

如果你发现自己经常使用Promise.resolve(setConf(...)),那么你可以为它创建一个实用函数:

function setConfPromise(...args) {
    return Promise.resolve(setConf(..args))
}

是否可以将现有函数声明为异步?

您可以更改它的声明,也可以用另一个函数包装它。您有时无法通过 async 行为动态地实现它,有时则不能。为此,您需要两个单独的函数。

你可以这样包装:

module.exports.asyncSetConf = function(...args) {
    return Promise.resolve(setConf(...args));
}
module.exports.setConf = setConf

仅供参考,async 仅应在实际需要时使用。关于其用法的一些说明:

  1. 当不涉及实际的异步代码时,您永远不应该使用async。将异步接口放在同步代码上只会使函数的使用比所需的复杂。
  2. 当您想在函数内使用await 时,请使用async
  3. 当您强制自动返回一个 Promise 并自动捕获一些异常并变成一个被拒绝的 Promise 时,请使用 async

就个人而言,当我想在函数中使用await 时,我只会使用async

你不需要使用async 来返回一个promise。您可以通过返回一个承诺以“老式”方式做到这一点。

使用async 不会使任何同步代码突然异步运行(一个常见的新手假设)。它根本不会改变同步代码。它强制返回值是一个承诺,调用者必须使用await.then() 来获取将在.then() 上强制执行“下一个滴答”的值,但如果函数都是同步的,它仍然会同步执行 - async 不会改变这一点。

【讨论】:

    猜你喜欢
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2017-12-06
    • 2016-05-20
    • 2023-03-10
    • 2021-03-25
    相关资源
    最近更新 更多