在Promise链中使用await

18

我刚刚升级到Node 8,并想开始使用async/await。我遇到了一个错误,花了我一段时间才解决,我其实只是想知道是否有一种更优雅的方式。由于这将导致所有次要重构,我不想在这个时候重新设计整个函数。

async doSomething(stuff) {
...

  return functionThatReturnsPromise()
    .then((a) => ...)
    .then((b) => ...)
    .then((c) => {
      const user = await someService.createUser(stuff, c);
      user.finishSetup();
    });
};

有没有一种方法可以在 Promise 链中使用 await 而不必重构链上方的所有内容为 async


4
难道不应该是.then(async (c) => { 才能是有效的吗? - Jaromanda X
在这个简单的例子中,我不需要使用 await,但是在我的真实代码中,有一些需要对用户进行处理的东西。 - jensengar
3
是的,await 只能在 async 函数内部使用。如果一个函数在 async 函数内部,除非它本身也被标记为 async,否则它不是异步函数。 :p - Jaromanda X
1
我不明白的是,整个函数都是一个“async”函数,为什么该函数仍在使用promises。 - Joseph
你在说哪些“次要重构”?是将承诺链中的所有其他函数都变成异步函数。虽然这只是小事,但问题更多地涉及到不必重构整个函数。 - jensengar
显示剩余6条评论
1个回答

26

回调函数没有声明为async函数。您只能直接在async函数内部awaitPromise

async doSomething(stuff) {
// ...

  return functionThatReturnsPromise()
    .then((a) => /* ... */)
    .then((b) => /* ... */)
    .then(async (c) => {
      const user = await someService.createUser(stuff, c);
      return user;
    });
};

此外,如果您正在利用 async 函数,就不应该需要使用 then

async doSomething(stuff) {
// ...

  const a = await functionThatReturnsPromise();
  const b = // ...
  const c = // ...
  const user = await someService.createUser(stuff, c);
  return user;
};

是的,我现在明白了,感谢@Jaromanda X。我也明白,如果我将整个函数转换为async/await,这不会成为一个问题,但这是应用程序的核心功能,我宁愿不去碰更多,因此努力保留promise链并只添加我需要的新部分。 - jensengar
如果我将整个函数都转换为异步/等待,你指的是什么?您可以从async函数内部await任何Promise - Kyle Richardson
现在整个函数是一个很长的 Promise 链。我想避免将链中的每个“链接”转换为 await - jensengar
调用代码不应需要重构,无论是调用异步函数还是返回 Promise 的常规函数,都不会有任何区别。根据规范,当调用异步函数时,它将返回一个 Promise。 - thgaskell
@CodesLikeA_Mokey 我明白了,这是个好决定 :) 希望未来会有一些测试,使得像那样的重大重构变得不那么不确定。 - thgaskell
@jensengar 只是一个小技巧,Visual Studio Code 可以通过右键将整个 Promise 链代码转换为 async/await。 - LumbusterTick

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