Implement a combination of Promise.all and Promise.settle

I need to implement a version Promise.allthat takes an array of promises and returns the result, as it usually does, plus also installs all promises, just like Promise.settleit does in Bluebird>, except that I cannot use it Bluebirdand should only rely on the standard promise protocol.

Would it be terribly difficult to implement? Or is it too much to ask here about how to implement it? I really hope not, so I ask if anyone can possibly implement it earlier, share an idea on how to do it right.

The premise for this is to be able to use it in a database transaction that must complete commit/ rollbackafter the call is completed, and cannot lose promises while still trying to allow an external call transaction.

EDIT: The link provided to another question is very useful, but this is not a complete answer to the question asked. General settleis a great example that helped a lot, but it had to be simplified and included in the logic allto fit the transaction scenario described earlier.

+4
source share
3 answers

promiseSettle() , settle(), . .settle() , :

, promiseSettle(), promises , promises :

function promiseSettle(promises) {
    return new Promise(function(resolve) {
        var remaining = promises.length;
        // place to store results in original order
        var results = new Array(remaining);

        function checkDone() {
            if (--remaining === 0) {
                resolve(results);
            }
        }

        promises.forEach(function(item, index) {
            // check if the array entry is actually a thenable
            if (typeof item.then === "function") {
                item.then(function(value) {
                    // success
                    results[index] = {state: "fulfilled", value: value};
                    checkDone();
                }, function(err) {
                    // reject error
                    results[index] = {state: "rejected", value: err};
                    checkDone();
                });
            } else {
                // not a thenable, just return the item itself
                results[index] = {state: "fulfilled", value: item}
                --remaining;
            }
        });
        // special case for zero promises passed
        if (remaining === 0) {
            resolve(results);
        }
    });
}

, :

// Either fulfills with an array of results or
// rejects with the first error, but it does not do either
// until all promises have completed which makes it different than
// promise.all()
function promiseSettleAll(promises) {
    return promiseSettle(promises).then(function(results) {
        for (var i = 0; i < results.length; i++) {
            if (results[i].state !== "fulfilled") {
                // reject with the first error found
                throw results[i].value;
            }
        }
        // all were successful, return just array of values
        return results.map(function(item) {return item.value;});
    });
}
+3

, jfriend , settle, , .all.

, Bluebird newer reflect ( native promises), API :

function reflect(promise){
    return promise.then(x => ({state: "fulfilled", value: x}), // arrows, assume nodejs
                        e => ({state: "rejected" , value: e}));
}

, :

function settle(promises){
    return Promise.all(promises.map(reflect)); // much cleaner
}

, / , :

function allWait(promises){
    return settle(promises).then(results => {
       var firstFailed = results.find(r => r.state === "rejected");
       if(firstFailed) throw firstFailed.value;
       return results; 
    });
}
+7

, , (spex), .

, batch - , .

I am not retyping its source code here, because now it is much more than what was originally sought in the question.

0
source

Source: https://habr.com/ru/post/1606507/


All Articles