评估每个承诺的可重复承诺

时间:2020-07-19 10:46:23

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

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

让我们说A,C是必填项。

  • 承诺1的流程A,B
  • 承诺2的流程A,C
  • 承诺3个流程B,C。

在以下任何一种情况下我都可以返回

  1. P1,P2已完成(不在乎P3)
  2. P1,P3已完成(不在乎P2)
  3. P2,P3已完成(不在乎P1)
  4. P1,P2,P3已完成。

所有的promise(异步调用)顺序地从同一项目开始。 如何使用可迭代的Promise处理此问题??

我能想到的一种方法是

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

这应该有效。但这需要我根据所必需的项目和eachPromiseItems来构建承诺组合的列表。

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

2 个答案:

答案 0 :(得分:0)

作为可选建议。您可以创建一个承诺包装器,以处理所有承诺并在需要时解决它。

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

未测试代码

答案 1 :(得分:0)

我不确定该要求是否内置了某些内容,但是您可以运行一个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'));