JavaScript链接来自LocalFower for循环的承诺

JavaScript链接来自LocalFower for循环的承诺,javascript,for-loop,promise,chaining,localforage,Javascript,For Loop,Promise,Chaining,Localforage,我试图从LocalFow库中链接多个getItem承诺,这些键是从数组中读取的 问题: 我需要Resolve或Reject回调在所有LocalFour承诺完成后触发 这两种方法都没有正确的调用堆栈。有什么想法吗 代码1: function load(keyHandlerPairs, correct, incorrect) { var result = { resolved: 0, rejects: 0,

我试图从LocalFow库中链接多个
getItem
承诺,这些键是从数组中读取的

问题: 我需要Resolve或Reject回调在所有LocalFour承诺完成后触发

这两种方法都没有正确的调用堆栈。有什么想法吗

代码1:

function load(keyHandlerPairs, correct, incorrect) {
    var result = {
                    resolved: 0,
                    rejects: 0,
                },
                p = new Promise(function (resolve, reject) {
                    //Retrieve objects from localstorage;
                    if ($.isArray(keyHandlerPairs)) {
                        for (var i = 0; i < keyHandlerPairs.length; i++) {
                            var kv = keyHandlerPairs[i];
                            lf.getItem(kv.key, kv.handler).then(
                                //Resolved
                                function () { console.log('resolved'); result.resolved++; }
                            );
                        }
                    } else {
                        var kv = keyHandlerPairs;
                        lf.getItem(kv.key, kv.handler);
                    }


                    if ((result.resolved + result.rejects) == keyHandlerPairs.length) {
                        console.log(result.resolved, result.rejects, keyHandlerPairs.length);
                        resolve(result);
                    } else {
                        console.log(result.resolved, result.rejects, keyHandlerPairs.length);
                        reject(result);
                    }
                }).then(correct, incorrect);
}
if ($.isArray(keyHandlerPairs)) {
                        var promises = [];
                        for (var i = 0; i < keyHandlerPairs.length; i++) {
                            var kv = keyHandlerPairs[i];
                            promises.push(lf.getItem(kv.key, kv.handler));
                        }

                        Promise
                            .all(promises)
                            .then(function (value) { console.log(value); result.resolved++; })
                            .catch(function (error) { console.log(error); result.rejects++; });

                    } else {
                        var kv = keyHandlerPairs;
                        lf.getItem(kv.key, kv.handler);
                    }
功能加载(钥匙手柄对,正确,不正确){
var结果={
已解决:0,
拒绝:0,
},
p=新承诺(功能(解决、拒绝){
//从本地存储中检索对象;
if($.isArray(键盘手对)){
对于(var i=0;i
代码替换:

function load(keyHandlerPairs, correct, incorrect) {
    var result = {
                    resolved: 0,
                    rejects: 0,
                },
                p = new Promise(function (resolve, reject) {
                    //Retrieve objects from localstorage;
                    if ($.isArray(keyHandlerPairs)) {
                        for (var i = 0; i < keyHandlerPairs.length; i++) {
                            var kv = keyHandlerPairs[i];
                            lf.getItem(kv.key, kv.handler).then(
                                //Resolved
                                function () { console.log('resolved'); result.resolved++; }
                            );
                        }
                    } else {
                        var kv = keyHandlerPairs;
                        lf.getItem(kv.key, kv.handler);
                    }


                    if ((result.resolved + result.rejects) == keyHandlerPairs.length) {
                        console.log(result.resolved, result.rejects, keyHandlerPairs.length);
                        resolve(result);
                    } else {
                        console.log(result.resolved, result.rejects, keyHandlerPairs.length);
                        reject(result);
                    }
                }).then(correct, incorrect);
}
if ($.isArray(keyHandlerPairs)) {
                        var promises = [];
                        for (var i = 0; i < keyHandlerPairs.length; i++) {
                            var kv = keyHandlerPairs[i];
                            promises.push(lf.getItem(kv.key, kv.handler));
                        }

                        Promise
                            .all(promises)
                            .then(function (value) { console.log(value); result.resolved++; })
                            .catch(function (error) { console.log(error); result.rejects++; });

                    } else {
                        var kv = keyHandlerPairs;
                        lf.getItem(kv.key, kv.handler);
                    }
if($.isArray(keyHandlerPairs)){
var承诺=[];
对于(var i=0;i
我需要Resolve或Reject回调在所有LocalFour承诺完成后触发

lf.getItem
是异步的,但是在触发所有调用之后,您正在测试
(result.resolved+result.rejects)==keyHandlerPairs.length
.resolved
.rejects
仍将是
0
(请注意,您无论如何都不会增加拒绝次数)

首先,您不应该使用
Promise
构造函数,而应该为尚未支持承诺的单个异步API构造承诺。不应该有任何逻辑,只是一个简单的呼吁。假设您希望使用
Promise.all
等待所有并发运行的承诺,并将它们的组合结果作为数组的承诺。您的代码应该如下所示:

if (!$.isArray(keyHandlerPairs))
    keyHandlerPairs = [keyHandlerPairs];
var promises = keyHandlerPairs.map(function(kv) {
    return lf.getItem(kv.key, kv.handler);
});
return Promise.all(promises);

好吧,现在假设你实际上不关心结果和是否所有承诺都成功了,而只关心履行承诺和拒绝承诺的数量。好的,没有本机的组合函数,所以我们需要编写自己的函数(并使用
Promise
构造函数)。但是,此功能应该是通用的,与键值处理程序对无关

Promise.countResolutions = function(promises) {
    var result = {fulfillments:0, rejections:0},
        len = 0;
    return new Promise(function(resolve, reject) {
        function addResult(type) {
            result[type]++;
            if (result.fulfillments+result.rejections == len)
                resolve(result);
            return true;
        }
        try {
            let i = 0;
            for (let promise of promises) {
                let called = false;
                i++;
                promise.then(function onfulfilled() {
                    if (!called) called = addResult("fulfillments");
                }, function onrejected() {
                    if (!called) called = addResult("rejections");
                });
            }
            len = i;
            if (result.fulfillments+result.rejections == len)
                resolve(result);
        } catch (e) {
            reject(e);
        }
    });
};

是的,它并不像一开始看起来那么琐碎(好吧,也许上面的版本有点太详细了)。但是一旦你有了这个,你可以简单地用
.countResolutions()
替换第一个代码片段中的
.all()
,然后你就得到了预期的结果。

你真的是想按顺序链接它们,还是并行执行它们?我假设你使用Mozilla的ES6
Promise
?是的,我希望它们是并行链接的。我希望在每一个承诺都完成后,承诺都能兑现。好的,那么看看我的答案:-)我回家后会试试:我有一个关于你代码的问题。为什么使用“let”而不是“var”?它们之间的区别是什么?因此调用的
let
是for循环体的局部,而不是
函数(resolve,reject){
的局部,因为
var
的作用域(请参见)Firefox v32似乎不支持使用“let”。我在使用该代码时出现语法错误。因此我调整了计算承诺的方法(删除了调用的变量,更改了for loop,更改了addResult)我让它开始工作了!FIDDLE:Version,在计算时也会返回承诺的值:Hm,因为您使用的是本机承诺,我没想到您会避免使用和:-)不过,您似乎需要在FIDDLE选项中添加