JavaScript链接承诺来自for循环中的LocalForage
JavaScript chaining promises from LocalForage in for loop
我正试图从LocalForage库中链接多个getItem
承诺,密钥是从数组中读取的。
问题:在所有LocalForage承诺完成后,我需要Resolve或Reject回调来触发。
两个方法都没有正确的调用堆栈。有什么想法吗?
代码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);
}
代码alt:
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);
}
在所有LocalForage承诺完成后,我需要Resolve或Reject回调来触发。
是的。lf.getItem
是异步的,但在激发所有调用之后,您正在测试(result.resolved + result.rejects) == keyHandlerPairs.length
。.resolved
和.rejects
仍然是0
(请注意,无论如何都不会增加拒绝次数)。
首先,除了为还不支持promise的单个异步API构造promise之外,不应该使用Promise
构造函数。不应该有任何逻辑,只是一个简单的呼吁。假设您希望使用Promise.all
来等待所有并发运行的promise,并从中获得组合结果作为数组的promise。你的代码应该是这样的:
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()
,就可以得到预期的结果。
相关文章:
- jQuery:循环一个具有不同超时值的循环
- 在循环中分配json值时,值被覆盖
- 如何在下面的ES6循环中获得前面的文本
- 为什么“;未定义的“;在JavaScript中结束循环
- Javascript循环不会自我更新
- 如何使用jquery处理php循环通过元素
- 而循环只设置php中输入字段中的第一个值
- 循环遍历数组中的特定索引
- Javascript返回值只在循环中返回一次
- 按照选项卡索引的顺序循环一个jQuery选择
- 循环遍历以数组为值的Javascript对象
- 为什么JavaScript在for循环为3时向所有4发出警报
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- 循环结束/推送到数组之前在页面上呈现EJS
- 循环比赛位置算法
- jQuery循环在特定位置暂停
- 我的javascript for循环不起作用
- 循环浏览多个身体背景图像
- W3C循环样式的JavaScript
- JavaScript链接承诺来自for循环中的LocalForage