簡體   English   中英

來自forfor循環中LocalForage的JavaScript鏈接承諾

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM