异步函数作为回调函数

8

我刚开始使用async/await,对于它与回调的交互方式感到困惑。例如,

fooMethod(function() {
    return Promise.resolve("foo");
});

vs

fooMethod(async function() { //add async keyword
    return "foo";
});

必须以特定方式编写fooMethod,以便它可以处理async函数作为回调吗?

如果fooMethod是一个公共库,我如何确定添加async关键字到函数是安全的?

后续

Express路由器,

app.get('/foo', function (req, res) {
  return res.send("foo");
});



app.get('/foo', async function (req, res) {
  return res.send("foo");
});

这两个函数都可以工作,但使用它们是否安全呢?

@RoyiNamir 这只是一个简单的例子,我只是对与可能公共库的回调交互感到困惑。 - Zanko
@TamasHegedus 那是错误的——如果函数对返回值不做任何操作,那么它就不需要以不同的方式处理返回的Promises - Jed Fox
@JF 你的意思是如果函数以 cb() 结尾,那么我们可以安全地添加 async 关键字,但如果函数以 const result = cb() 结尾,则除非它解决了回调的 promise,否则它将不支持 async 关键字? - Zanko
Node支持async/await,因此使用它是安全的。但是,如果您没有为异步目的使用async函数,则没有意义。 - pizzarob
@realseanp 谢谢,是的,在那个异步函数中我将使用 await 等等。我的意思是,在查看 express 文档时,我发现没有关于使用 async 是否会对回调函数造成问题的文档。 - Zanko
显示剩余4条评论
2个回答

3

您的两个回调函数是等效的。一个async function只是一个返回Promise的常规function的语法糖。这意味着您可以像调用常规函数一样调用async function。以下是示例:

const foo = async function (arg) {
  return arg * 2
}
const bar = function (arg) {
  return Promise.resolve().then(() => {
    return arg * 2
  })
}

const fooReturn = foo(2)
const barReturn = bar(2)
console.log('foo(2) =>', fooReturn.toString())
console.log('bar(2) =>', barReturn.toString())

fooReturn.then(fooResult => console.log('await foo(2) =>', fooResult))
barReturn.then(barResult => console.log('await bar(2) =>', barResult))

然而,如果接收回调的代码需要获得响应,则不能使用异步函数,除非该代码专门设计用于检查回调函数返回值并在其为Promiseawait


嗨,那么我什么时候才能知道在回调中不能使用async关键字? - Zanko
@Zanko,我已经编辑了我的答案;这个编辑是否澄清了那个问题? - Jed Fox
我已经编辑了我的答案,你介意澄清后续问题吗?非常感谢! - Zanko
那里不应该有问题。另外,如果您觉得这个答案对您有帮助,请使用向上箭头进行点赞,或者点击灰色复选标记将其标记为被接受的答案。 - Jed Fox
是的,那就是要点。 - Jed Fox
显示剩余3条评论

0

你的两个函数是等价的,但下面演示了在 async 函数 中使用 await 会每次延迟一个额外的 tick 执行函数:

function syncTest() {
  console.log('sync completed')
  return Promise.resolve('foo')
}

async function asyncTest() {
  console.log('async completed')
  return 'foo'
}

async function awaitTest() {
  console.log('await started')
  await void 0
  console.log('await awaited')
  await void 0
  console.log('await completed')
  return 'foo'
}

console.log('start')

syncTest().then(value => console.log(`sync resolved: ${value}`))
asyncTest().then(value => console.log(`async resolved: ${value}`))
awaitTest().then(value => console.log(`await resolved: ${value}`))

Promise.resolve()
  .then(() => console.log('tick 2 completed'))
  .then(() => console.log('tick 3 completed'))
  .then(() => console.log('tick 4 completed'))

console.log('tick 1 completed')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接