简体   繁体   中英

Iterable Promises with evaluation for each promise

I have a list of items to be processed. Lets says A,B,C,D,E.. I have a list of promises which processes these items. Each promise can process 1 or more items. I have a list of items which need to be mandatorily processed.

Lets say A, C are mandatory items.

  • Promise 1 processes A,B
  • Promise 2 processes A,C
  • Promise 3 processes B,C.

I can return in any of the following cases

  1. P1,P2 are completed (don't care about P3)
  2. P1,P3 are completed (don't care about P2)
  3. P2,P3 are completed (don't care about P1)
  4. P1,P2,P3 are completed.

All promises (async calls) are started at the same item sequentially. How do I handle this with Promise of iterables.?

One way I could think of is

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

This should work. But this requires me to construct the list of promise combinations based on the mandatoryItems and eachPromiseItems.

Is there a proper elegant way to handle this case in JavaScript?

As an optional advice. You can create a promise wrapper to process all of your promises and resolve it whenever you want.

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

THE CODE NOT TESTED

I'm not sure that there is something built-in for this requirement but you can run over an array of promises and handle this logic like this:

 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'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM