[英]JavaScript chaining promises from LocalForage in for loop
我正在嘗試從LocalForage庫中鏈接多個getItem
Promise,這些鍵是從Array中讀取的。
問題:我需要Resolve或Reject回調來觸發所有LocalForage承諾完成之后。
兩種方法都沒有正確的調用棧。 有任何想法嗎?
代碼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);
}
我需要Resolve或Reject回調在所有LocalForage承諾完成后觸發。
是。 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);
}
});
};
是的,它並不像初看起來那么瑣碎(好,也許上面的版本太詳細了)。 但是,一旦你有了這個,你可以簡單地替換.all()
通過在第一個片段.countResolutions()
你會得到預期的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.