【问题标题】:Iterable Promises with evaluation for each promise对每个 Promise 进行评估的 Iterable Promises
【发布时间】:2020-11-08 18:03:23
【问题描述】:

我有一个要处理的项目列表。让我们说 A、B、C、D、E .. 我有一个处理这些项目的承诺列表。每个 Promise 可以处理 1 个或多个项目。我有一份需要强制处理的项目清单。

假设 A、C 是必填项。

  • Promise 1 进程 A,B
  • Promise 2 进程 A,C
  • 承诺 3 个流程 B、C。

我可以在以下任何情况下返回

  1. P1,P2 已经完成(P3 不用管)
  2. P1,P3 已经完成(P2 不用管)
  3. P2,P3 已经完成(不用管 P1)
  4. P1、P2、P3 已完成。

所有的 Promise(异步调用)都是从同一个项目按顺序启动的。 我如何使用 Promise of iterables 来处理这个问题?

我能想到的一种方法是

Promise.race(
    Promise.all(P1,P2),
    Promise.all(P1,P3),
    Promise.all(P2,P3),
    Promise.all(P1,P2,P3)
)

这应该可行。但这需要我根据mandatoryItems 和eachPromiseItems 来构造promise 组合列表。

在 JavaScript 中是否有适当的优雅方式来处理这种情况?

【问题讨论】:

  • Promise.race 会将第一个承诺返回给fullfilreject。所以,你可能需要一些机制来运行所有的 Promise,并告诉你什么被实现,什么被拒绝。我可以考虑结合.all.race 和这里的答案stackoverflow.com/questions/31424561/…
  • 您的意思是要忽略非强制性项目的失败(拒绝承诺),还是要尽快返回所有承诺必填项都满足了吗?
  • 在所有组合中,只要一个承诺组合解决,我就想返回。我可以接受其他需要时间的组合。但我绝对想捕捉对组合的拒绝。 @Bergi
  • @SenthilVidhiyakar 好的,所以你的代码可以工作,你真的想要Promise.race 而不是Promise.anyPromise.allSettled。但是我并不真正理解这个例子 - 如果只有项目 A 和 C 是强制性的,并且两者都由 Promise P2 处理,那么单独 P2 是否就足够了?和Promise.all(P1,P2,P3) 竞争是没有用的,因为无论如何子集总是会比这更早解决。
  • with Promise of iterables.”到底是什么意思?解决方案“要求我根据mandatoryItems 和eachPromiseItems 构建promise 组合列表。”——这有什么问题?您是否在问如何动态构建该列表?那么请分享输入数据结构。

标签: javascript ecmascript-6 promise async-await es6-promise


【解决方案1】:

作为可选建议。您可以创建一个 Promise 包装器来处理您的所有 Promise 并随时解决它。

function afterPromises(yourPromiseList, checker) {
    var _P = new Promise((res, rej) => {
        for (var p of yourPromiseList) {
            p.then((data) => {
                let checked = checker(data);
                if(checked===true){
                    res()
                }
                if(checked===false){
                    rej()
                }
            })
        }
    })
    return _P;
}

afterPromises([...yourPromiseList], () => {
    var itemsDict = {}// a closure var to register which your items processed
    return (data) => {
        itemsDict[data.id]=true
        //And your extra logic code
        return true
        //or return false
        //or reutrn undefined
    }
}).then(()=>{
    //resolved
})

代码未测试

【讨论】:

    【解决方案2】:

    我不确定是否有针对此要求的内置功能,但您可以运行一组 promise 并像这样处理此逻辑:

    const p1 = new Promise(resolve => {
      setTimeout(() => {resolve(['A','B']);}, 500);
    });
    
    const p2 = new Promise(resolve => {
      setTimeout(() => {resolve(['A','C']);}, 500);
    });
    
    const p3 = new Promise(resolve => {
      setTimeout(() => {resolve(['B','C']);}, 500);
    });
    
    const mandatory = ['A','C'];
    
    function promisesRunTillMandatoryCompleted(promises, mandatory) {
        return new Promise((resolve, reject) => {
           let results = [];
           let completed = [];
           
           promises.forEach((promise, index) => {
                Promise.resolve(promise).then(result => {
                    results[index] = result;
                    completed = [...new Set(completed.concat(result))];
                    
                    if (mandatory.every(elem=> completed.indexOf(elem) > -1)) {
                        resolve(results);
                    }
                }).catch(err => reject(err));
           });
        });
    }
    
    promisesRunTillMandatoryCompleted([p1,p2,p3],mandatory)
    .then(() => console.log('all mandatory commpleted'));

    【讨论】:

      猜你喜欢
      • 2019-04-02
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多