簡體   English   中英

JavaScript承諾不能與resolve()一起使用

[英]JavaScript promise not working with resolve()

我在JavaScript中對Promise遇到了一些問題。 所以我想做的是我想從Firebase檢索,然后將所有返回的結果存儲到數組中。 之后,我將對數組進行一些排序。 這是我的代碼:

    let promise = new Promise((resolve, reject) => {
    var query = firebase.database().ref('');
        query.once( 'value', data => {
            data.forEach(subtypeSnapshot => {
                var itemData = ;

                var query = firebase.database().ref('').child(itemKey);
                query.once( 'value', data => {
                    var itemDetail = ;
                    datasetarr.push();
                });
            }); 
            resolve(datasetarr);
        });             
    });

通過這組代碼,從promise中的第一個console.log ,我設法在控制台中獲得了這些代碼:

有了這些,這意味着我的Firebase檢索沒有任何問題。 之后,我想將它們分別存儲到數組中,這是一部分:

datasetarr.push({type: subtype, quantity: quantity});

完成所有工作后,我解決了諾言,當諾言完成后,我將打印出數組中的項目。 但是, .then()內的for循環不會輸出任何內容。 有任何想法嗎?

如前所述:您的承諾早就解決了。

您可以使用Promise.all來解決所有諾言,然后再解決包裝的Promise。 我整理了一個簡單的示例,但是由於缺少Firebase數據庫,我僅使用返回Promises的函數: https : //jsfiddle.net/57b0gkLt/

根據query.once('value') 文檔query.once('value')返回一個Promise,所以這應該可行。

編輯 :這樣

var datasetarr = [];
let promiseItemDataList = new Promise((resolve, reject) => {
var query = firebase.database().ref('receiptItemIDsByCategory').child(category);
    query.once( 'value', data => {
        var promises = []; // NEW LINE

        data.forEach(subtypeSnapshot => {
            var itemData = subtypeSnapshot.val();
            var itemKey = subtypeSnapshot.key;

            var query = firebase.database().ref('receiptItems').child(itemKey);
            var promise = query.once('value'); // NEW LINE
            promises.push(promise); // NEW LINE

            promise.then(data => { // .then instead of a callback
                var itemDetail = data.val();
                var subtype = itemDetail.type;
                var quantity = itemDetail.quantity;
                console.log('inside promise ' + subtype + ' ' + quantity);
                datasetarr.push({type: subtype, quantity: quantity});
            });
        }); 

        Promise.all(promises).then(() => resolve(datasetarr)); // NEW LINE
    });             
});

promiseItemDataList.then((arr) => {
    for(var i = 0; i < arr.length; i++){
        console.log('outside promise ' + arr[i].type + ' ' + arr[i].quantity);
    }
});

您第一次檢索初始數據集的async調用已正確處理,但.forEach循環未調用后續調用。

query.once( 'value', data => {
    var itemDetail = data.val();
    var subtype = itemDetail.type;
    var quantity = itemDetail.quantity;
    console.log('inside promise ' + subtype + ' ' + quantity);
    datasetarr.push({type: subtype, quantity: quantity});
});

問題是您要在其他異步調用返回之前resolving承諾。

我不確定query.once處理callback確切程度。 它看起來不像在做諾言,也不像傳統的callback function那樣。

您可以采取work-around是將forEach.async調用包裝到Promise對象中,然后使用Promise.all([list_of_promises])集合,以確保在resolving主對象之前返回了每個調用諾言。

偽代碼:

var datasetarr = [];
let promiseItemDataList = new Promise((resolve, reject) => {
    var query = firebase.database().ref('receiptItemIDsByCategory').child(category);
    query.once( 'value', data => {

        // Collect a list of promises for the sub item async calls
        var get_data_promises = [];
        data.forEach(subtypeSnapshot => {
            get_data_promises.push(new Promise(function(resolve) {
                var itemData = subtypeSnapshot.val();
                var itemKey = subtypeSnapshot.key;
                var query = firebase.database().ref('receiptItems').child(itemKey);

                query.once( 'value', data => {
                    var itemDetail = data.val();
                    var subtype = itemDetail.type;
                    var quantity = itemDetail.quantity;
                    console.log('inside promise ' + subtype + ' ' + quantity);
                    datasetarr.push({type: subtype, quantity: quantity});
                    resolve("Done");
                });
        }))

        // Fire them all - Once done resolve the main promise.
        Promise.all(get_data_promises).done(function() { resolve(datasetarr); });
    });
});
var query = firebase.database().ref('receiptItemIDsByCategory').child(category);

query.once('value')
.then((data) => {
    promises =[]
    data.forEach( subtypeSnapshot => {
        var itemData = subtypeSnapshot.val();
        var itemKey = subtypeSnapshot.key;

        var query = firebase.database().ref('receiptItems').child(itemKey);
        p = query.once( 'value', data => {
                    var itemDetail = data.val();
                    var subtype = itemDetail.type;
                    var quantity = itemDetail.quantity;
                    console.log('inside promise ' + subtype + ' ' + quantity);
                });
        promises.push(p)
    })
    return promises
})
.then ((arrayofpromises) => {
    Promise.all(arrayofpromises)
    .then((results)=>{
        console.log(results)
    })
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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