实现Promise.all和Promise.settle的混合 [英] Implementing a mix of Promise.all and Promise.settle

查看:210
本文介绍了实现Promise.all和Promise.settle的混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要实现一个 Promise.all 的版本,它会接受一系列的promises并像往常那样返回结果,并且还会解决所有的承诺,就像 Promise.settle Bluebird 库中执行此操作,但我无法使用 Bluebird ,并且必须仅依赖于标准的承诺协议。

I need to implement a version of Promise.all that would take an array of promises and return the result as it usually does, plus also settles all promises, much like Promise.settle does it within the Bluebird library, except I cannot use Bluebird, and have to rely just on the standard promise protocol.

实施起来会非常复杂吗?或者在这里问一下如何实现它的想法太过分了?我真的希望不是,所以我问,如果有人可能之前实现它,分享如何做正确的想法。

Would that be terribly complicated to implement? Or is it too much to ask here for an idea of how to implement it? I really hope not, so I'm asking, if anyone perhaps implemented it before, to share the idea of how to do it right.

这个的前提是能够在一个数据库事务中使用它,一旦调用完成,它需要做 commit / rollback 在交易电话会议之外仍然无法解决松散的承诺。

The premise for this is to be able to use it within a database transaction that needs to do commit/rollback once the call has finished, and it cannot have loose promises still trying to resolve outside the transaction call.

编辑:提供给另一个问题的链接非常有用,但它是对问题没有完整的答案。通用的是一个很好的例子,它有很多帮助,但它需要简化并包装到所有逻辑中适合前面描述的交易场景。

The link provided to another question is very useful, but it is not a complete answer to the question that was asked. A generic settle is a great example that helped a lot, but it needed to be simplified and wrapped into all logic to fit the transactions scenario described earlier.

推荐答案

建立在通用 promiseSettle()来自另一个问题的功能,你可以做到这一点并拥有一个通用的结束()类型函数和你更具体的版本作为它的包装。这将为您提供执行大量 .settle()行为类型的通用功能,并具有您自己的特定风格,并根据需要构建其他特定风格:

Building on the generic promiseSettle() function from the other question, you could do this and have both a generic settle() type function and your much more specific version as a wrapper around it. This would give you the generic ability to do lots of .settle() types of behavior and have your own specific flavor and also build other specific flavors as needed:

所以,这里是通用的 promiseSettle(),它返回所有承诺的状态并仅在所有传入时解析承诺完成:

So, here's the generic promiseSettle() that returns you the state of all the promises and resolves only when all the passed-in promises are done:

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

而且,这里有一个包装器,它可以为您提供特定的行为:

And, here's a wrapper on it that gives you your specific behavior:

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

这篇关于实现Promise.all和Promise.settle的混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆