使用Babel在调用或应用异步函数时等待

7

如何使用 Babel 在使用 callapply 调用的 async 函数上进行 await?

以下是一个示例,其中 getOrdersService 类的一个 async 方法:

class Service() {
   async getOrders(arg1, arg2, arg3) {
      return await this.anotherService.getOrders(arg1, arg2, arg3);
   }
}

let service = new Service();
// ...
// Babel doesn't compile 
// let stream = await service.getOrders.call(this, arg1, arg2, arg3);
// producing SyntaxError: Unexpected token for await
let stream = service.getOrders.call(this, arg1, arg2, arg3);
stream.pipe(res); // obviously not working without await in the prev line

你是在问当你想在另一个异步函数外部调用异步函数时该怎么做吗?不清楚这与call/apply/bind有什么关系,或者在你的问题中传递给call的this是什么。 - loganfsmyth
@loganfsmyth 不是,我在问如何在使用 callapply 调用的 async 函数上进行 await - krl
你可以像平常一样使用await。我已经更新了我的答案。 - loganfsmyth
@loganfsmyth call 不是一个 async 函数(尽管在这种情况下它调用了一个 async 函数),所以在这里使用 await 是无效的,至少目前在 babel 中是这样。 - krl
await 只是等待一个 Promise。例如:var streamPromise = service.getOrders(); var stream = await streamPromise;。你使用 call 只是改变了调用 getOrders 的方式,它并不影响 await 的工作原理。如果你有一个具体的示例无法正常工作,请将其添加到你的问题中。 - loganfsmyth
3个回答

10

async function是返回一个Promise的函数,而await则接受一个Promise。并不要求所有的async函数都必须通过await调用。如果你想在标准JS函数中使用一个async函数,那么你可以直接使用返回的Promise结果。在你的情况下,通过.call调用函数仍然会像其他函数一样返回一个Promise,因此你需要将该Promise传递给await:

async function doThing(){
  let service = new Service();

  var stream = await service.getOrders.call(this, arg1, arg2, arg3)
  stream.pipe(res);
}

这是我期望的,但是 babel 目前似乎不支持它。 - krl
请提供一个在Babel中演示这个问题的例子,因为它肯定也可以在那里工作。您当前的示例甚至没有使用await。 - loganfsmyth
你必须将await放在一个异步函数中。这就是我之前问过“当你想在另一个异步函数外调用异步函数时该怎么办?”的原因,而你回答说不需要。 - loganfsmyth
为了在函数中使用 await something;,该函数必须是一个异步函数。在您的情况下,您的 let service = new Service(); 等语句不在异步函数内。 - loganfsmyth
让我们在聊天中继续这个讨论 - loganfsmyth
显示剩余2条评论

0

来自OP

问题在于let stream = service.getOrders.call(this, arg1, arg2, arg3);位于常规函数内的匿名函数中。我没有将匿名函数标记为async,而是将常规函数标记为async,导致Babel出现SyntaxError: Unexpected token

感谢@loganfsmyth带领我找到解决方案。


-4
你可以尝试使用这样的包装器:
class Service() {
   async getOrders(arg1, arg2, arg3) {
   // ....
   };
   wrappedOrders(arg1, arg2, arg3) {
       let res = await getOrders(arg1, arg2, arg3);
       return res;
   }
}

这样调用wrappedOrders:

let stream = service.wrappedOrders.call(this, arg1, arg2, arg3);

2
每个带有await的函数都是async的,因此wrappedOrders也必须是async的,这就让我们回到了我的问题。 - krl

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