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

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

问题描述

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

  const {eachLimit} = require(async); 

函数myFunction(){
返回新Promise(async(resolve,reject)=> {
eachLimit((等待getAsyncArray),500,(item,callback)= > {
//做其他使用原生承诺的事情。
},(错误)=> {
如果(错误)返回拒绝(错误);
//解决这里传递下一个值。
});
});
}

如你所见,我不能宣布 myFunction 作为异步函数,因为我无法访问 eachLimit 函数的第二个回调中的值。

解决方案

你在promise构造函数执行函数中有效地使用了promise,所以这个 Promise构造函数反模式



您的代码是主要风险的一个很好的例子:不安全地传播所有错误。了解那里的原因。



此外,使用 async / 等待可以使相同的陷阱更令人惊讶。比较:



  let p = new Promise(resolve => { (); // TypeError resolve();});(async()=> {await p;})()。catch(e => console.log(Caught:+ e)); //抓住它。 



带有天真(错误) async 等价物:



  let p = new Promise(async resolve => {(); // TypeError resolve();});(async()=> {await p;})()。catch(e => console。 log(Caught:+ e)); //不抓住它! 



查看浏览器的网页最后一个控制台。



第一个是有效的,因为Promise构造函数执行函数中的任何立即异常都会方便地拒绝新构造的promise(但是在任何 .then 里面你自己)。



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

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



您的代码



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

  async function myFunction(){
let array = await getAsyncArray();
返回新的Promise((解析,拒绝)=> {
eachLimit(数组,500,(item,callback)=> {
//执行使用本机承诺的其他内容。
},错误=> {
if(错误)返回拒绝(错误);
//此处通过传递下一个值解析。
});
} );
}

虽然为什么在时使用过时的并发控制库?等待


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.
   });
 });
}

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.

解决方案

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.

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.

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!

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

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).

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

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

Your code

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.
    });
  });
}

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

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

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