在新的 Promise() 构造函数中使用 async/await 是一种反模式吗? [英] Is it an anti-pattern to use async/await inside of a new Promise() constructor?

查看:24
本文介绍了在新的 Promise() 构造函数中使用 async/await 是一种反模式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the async.eachLimit function to control the maximum number of operations at a time.

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 函数的第二个回调中的值.

As you can see, I can't declare the myFunction function as async because I don't have access to the value inside the second callback of the eachLimit function.

推荐答案

您在 promise 构造函数执行器函数中有效地使用了 promise,因此 Promise 构造器反模式.

You're effectively using promises inside the promise constructor executor function, so this the Promise constructor anti-pattern.

您的代码是主要风险的一个很好的例子:没有安全地传播所有错误.阅读为什么那里.

Your code is a good example of the main risk: not propagating all errors safely. Read why there.

此外,async/await 的使用可以让同样的陷阱更加令人惊讶.比较:

In addition, the use of async/await can make the same traps even more surprising. Compare:

let p = new Promise(resolve => {
  ""(); // TypeError
  resolve();
});

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

与一个天真的(错误)async 等效:

with a naive (wrong) async equivalent:

let p = new Promise(async resolve => {
  ""(); // TypeError
  resolve();
});

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

在浏览器的 Web 控制台中查看最后一个.

Look in your browser's web console for the last one.

第一个有效,因为 Promise 构造函数执行器函数中的任何 immediate 异常都方便地拒绝了新构造的 Promise(但在任何 .then 中,您都需要依靠自己).

The first one works because any immediate exception in a Promise constructor executor function conveniently rejects the newly constructed promise (but inside any .then you're on your own).

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

The second one doesn't work because any immediate exception in an async function rejects the implicit promise returned by the async function itself.

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

Since the return value of a promise constructor executor function is unused, that's bad news!

没有理由不能将 myFunction 定义为 async:

There's no reason you can't define myFunction as async:

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 时,为什么还要使用过时的并发控制库?

Though why use outdated concurrency control libraries when you have await?

这篇关于在新的 Promise() 构造函数中使用 async/await 是一种反模式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆