一尘不染

在新的Promise()构造函数中使用async / await是一种反模式吗?

javascript

我正在使用该async.eachLimit函数来控制一次最大操作数。

const { eachLimit } = require("async");

function myFunction() {
 return new Promise(async (resolve, reject) => {
   eachLimit((await getAsyncArray), 500, (item, callback) => {
     // do other things that use native promises.
   }, (error) => {
     if (error) return reject(error);
     // resolve here passing the next value.
   });
 });
}

如您所见,我无法将该myFunction函数声明为异步的,因为我无权访问该eachLimit函数的第二个回调中的值。


阅读 517

收藏
2020-04-25

共1个答案

一尘不染

您实际上在promise构造函数执行程序函数内使用了promise,因此这是Promise构造函数anti-pattern。

您的代码很好地说明了主要风险:没有安全地传播所有错误。读为什么在那里。

此外,使用async/ await会使相同的陷阱更加令人惊讶。相比:

let p = new Promise(resolve => {

  ""(); // TypeError

  resolve();

});



(async () => {

  await p;

})().catch(e => console.log("Caught: " + e)); // Catches it.

天真(错误)的async等效项:

let p = new Promise(async resolve => {

  ""(); // TypeError

  resolve();

});



(async () => {

  await p;

})().catch(e => console.log("Caught: " + e)); // Doesn't catch it!

在浏览器的网络控制台中查找最后一个。

第一个起作用是因为Promise构造函数执行程序函数中的任何立即异常都可以方便地拒绝新构造的Promise(但是.then在您自己的任何内部)。

第二个不起作用,因为async函数中的任何立即异常都会拒绝 函数本身 返回async_的 _隐含承诺

由于未使用promise构造函数执行程序函数的返回值,所以这是个坏消息!

您的密码

没有理由不能定义myFunctionasync

async function myFunction() {
  let array = await getAsyncArray();
  return new Promise((resolve, reject) => {
    eachLimit(array, 500, (item, callback) => {
      // do other things that use native promises.
    }, error => {
      if (error) return reject(error);
      // resolve here passing the next value.
    });
  });
}

虽然为什么要在使用时使用过时的并发控制库await

2020-04-25