【问题标题】:How to promisify using providing some limit如何使用提供一些限制来承诺
【发布时间】:2021-10-20 08:53:36
【问题描述】:

我有这个功能。 simIds 数组长度为 1000(未知)。所以我需要让它可以一次承诺50,然后去争取下一个950,依此类推。那我怎么能做到这样。谢谢!!!

if(simIds.length < 0) {
  simIds.forEach((simid) => {
    promises.push(
      new Promise(function (resolve) {
      simService.getSimcardBasedonAction(userid, [simid], action)
      .then((result) => {
          if (result.success) {
          const simDetail = result.simcards[0];
          resolve(result)
        }
      })
    }));
  });
  Promise.all(promises)
  .then((result) => {
    console.log('result', result)
  })
}

【问题讨论】:

  • 顺便说一句,没有必要将你的电话getSimcardBasedonAction包装在另一个Promise中,这已经是一个承诺了。

标签: javascript node.js asynchronous async-await promise


【解决方案1】:

给定一个采用一组项目的方法、一个batchSize 和一个将一个项目转换为承诺的方法,您可以简单地将它们批处理并await 结果

const batchPromisify = async (arr, batchSize, makePromise) => {
    while(arr.length) {
        const batch = arr.splice(0,batchSize);        
        const promises = batch.map(makePromise);            
        await Promise.all(promises);
    }
}

这是一个带有整数数组的实时示例,以及一个仅模拟短暂延迟的异步方法。您可以看到传入的makePromise 回调只是将数组中的整数延迟包装,然后是控制台日志,说明该项目已完成。我还使用控制台日志包装了对批处理的调用,因此您可以在此示例中看到它一次运行 10 个:

const delay = (ms) => new Promise(resolve => setTimeout(resolve,ms));

const items = new Array(100).fill(0).map ( (_,i) => i);


const batchPromisify = async (arr, batchSize, makePromise) => {
    while(arr.length) {
        const batch = arr.splice(0,batchSize);        
        const promises = batch.map(makePromise);
        
        console.log("starting batch")
        await Promise.all(promises);
        console.log("finished batch")
    }
}

batchPromisify(items, 10, i => delay(100).then(_ => console.log("finished", i)));

在您的代码中使用它看起来像

batchPromisify(simIds, 50, 
    simId => simService.getSimcardBasedonAction(userid, [simid], action))

由于getSimcardBasedonAction 已经返回一个,因此无需将您的呼叫包装在另一个Promise 中!


现在说你想把结果出来,可以对batchPromisify做一个小改动:

const delay = (ms) => new Promise(resolve => setTimeout(resolve,ms));

const items = new Array(100).fill(0).map ( (_,i) => i);


const batchPromisify = async (arr, batchSize, makePromise) => {
    const results = [];
    while(arr.length) {
        const batch = arr.splice(0,batchSize);        
        const promises = batch.map(makePromise);
        
        results.push(await Promise.all(promises));
    }
    return results;
}

(async function(){
  const result = await batchPromisify(items, 10, i => delay(100).then(_ => i.toString()));
  console.log(result.flat());
})();

注意,在这种情况下,我不得不将await 调用到batchPromisify,并且为了演示目的,我更改了makePromise 返回与整数等效的字符串。调用的结果是一个数组数组,表示每个批次和其中的结果。如果您希望将所有结果放在 1 个数组中,您始终可以使用 .flat() 来展平此数组。

现在你的代码是

    const results = await batchPromisify(simIds, 50, 
             simId => simService.getSimcardBasedonAction(userid, [simid], action));
    const flatResults = results.flat();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2021-11-15
    相关资源
    最近更新 更多