在另一个承诺中解决承诺

时间:2017-03-14 04:27:43

标签: javascript node.js promise resolve

在NodeJS中,当解决方案属于另一个承诺时,我试图解决外部承诺。调用外部解析,但内部解析不是。

这是为什么?难道不能将决议传递到内部承诺并从new Promise(function(resolve...)解析父决心吗?

function doIt() {
    return new Promise(function(resolve) {
        // resolve('resolve called!'); // This works
        Object.keys(objects).forEach(function(key) {
            return deptSettings(key)
             .then(function(settings) { 
                 ... do stuff
                 if (no more stuff) 
                    resolve('inside resolve called!'); // Not called
            });
        });
    });
}

2 个答案:

答案 0 :(得分:4)

您所拥有的内容可以正常工作 - 适用于在forEach内解析的第一个承诺。之后,将忽略所有后续resolve次调用。

听起来你有许多事要做,并希望doIt返回一个在完成后解决的承诺。假设它们可以并行运行,那么你可以使用Promise.all

function doIt() {
    return Promise.all(
        Object.keys(objects).map(function(key) {
            return deptSettings(key)
                .then(function(settings) { 
                    // ... do stuff
                    // Return final result (for this deptSettings)
                });
        })
    );
}
doIt创建的所有承诺解决时(或当第一个承诺拒绝时),

Object.keys(...).map的承诺将解决。分辨率值将是上面Return final result返回的值的数组。

来自对该问题的评论:

  

所以不应该解决那个单一的承诺并快速解决剩下的任何调用吗?

这表示您希望根据某些条件解决承诺一次,并将您在Object.keys中执行的剩余工作短路。如果是这样,您可以删除第一个resolve以及已解决的第一个deptSettings承诺会触发resolve的单个doIt - 但是有一个惯用的相关内容,是Promise.race

function doIt() {
    return Promise.race(                           // Only change is here
        Object.keys(objects).map(function(key) {
            return deptSettings(key)
                .then(function(settings) { 
                    // ... do stuff
                    // Return final result (for this deptSettings)
                });
        })
    );
}

race根据结算的第一个数组(好的,任何可迭代的)承诺和结算(结算或拒绝)。

答案 1 :(得分:0)

您无法将forEach循环与Promise混合。同步和异步不应该混合在一起。

您可以做的是拥有一组promise,并使用Promise.all来确保解析数组中的所有promise。

例如:

    var myPromises = [];
    Object.keys(objects).forEach(function(key) {
        myPromises.push(your-function-that-returns-a-promise)
    });

    return Promise.all(myPromises).then(
        // do stuff after
    );

这是example