首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript多个promises导致null

JavaScript多个promises导致null
EN

Stack Overflow用户
提问于 2017-08-01 18:36:55
回答 1查看 117关注 0票数 1

我对JavaScript的承诺有些问题。下面是我的代码:

代码语言:javascript
复制
//removed code

我添加了一些注释来解释我正在尝试做的事情。现在的问题是,我获取了receiptID并创建了另一个promise variable,并将其推送到promise数组中,那里的console.log正在打印结果。

但是,在我注释掉该行并尝试在.then()中打印结果后,promise done消息被打印出来,但是没有来自数组的结果,也没有错误消息,这意味着异步执行没有正确完成。

有什么办法解决这个问题吗?在进阶时谢谢!

EN

回答 1

Stack Overflow用户

发布于 2017-08-01 18:54:02

您的代码中没有任何东西等待这些从属承诺。因为您没有从then处理程序返回任何内容,所以当您的处理程序完成时,then返回的承诺将立即实现。因此,您等待的是第一级承诺(放入promises中的承诺),而不是查询接收详细信息的承诺。

关于promise的一个关键问题是,then返回一个新的promise;它是一个管道,每个then (和catch)处理程序都可以在其中修改传递的内容。由then (或catch)返回的promise将使用then处理程序的返回值来实现,如果它不是类似promise ("thenable")的值,则将被解析为then处理程序的返回值,这意味着它将根据其他promise所做的事情来实现或拒绝。(仅供参考,我在我的博客上的中进入了promise术语-“履行”与“解决”,等等。)

因此,您应该从等待接收的then处理程序中传播一些内容;可能是Promise.all的结果。我会通过将其分解为单独的函数来实现(至少在two中:一个获取外层,不管它是什么,另一个获取该层的收据)。

还要注意,没有理由在您的顶层显式地创建新的promise。您已经有了一个:来自once的那个。

如果我理解正确的话,我在这里重新组织了一下,根据项目获取收据信息,然后调用one来获取收据,而不是调用每个项目,并从收据中获取分支详细信息。请参阅评论:

代码语言:javascript
复制
const promiseDataList =
    // Get all receipt items for the category
    firebase.database().ref('receiptItemIDsByCategory').child(category).once('value').then(itemIds => {
        // Build a map of receipt info keyed by receipt ID by getting all of the items and, as
        // we get them, storing the receipt info in the map
        const receiptMap = new Map();
        return Promise.all(itemIds.map(itemSnapshot => {
            // Get the details of each receipt into a map keyed by receipt ID; since a receipt
            // can have multiple items, be sure to check the map before adding a new entry
            return firebase.database().ref('receiptItems').child(itemSnapshot.key).once('value').then(item => {
                const itemDetail = item.val();
                const price = itemDetail.price;
                const quantity = itemDetail.quantity;
                const itemTotal = price * quantity;
                const receiptEntry = receiptMap.get(itemDetail.receiptID);
                if (receiptEntry) {
                    // We already have this receipt, add to its total
                    receiptEntry.total += itemTotal;
                } else {
                    // New receipt
                    receiptMap.set(itemDetail.receiptID, {id: itemDetail.receiptID, total: itemTotal});
                }
            });
        })).then(() => {
            // We have the map of receipts we want info for; get all receipts so we can filter
            // for only the ones we want. (Note: Surely we could use the keys from receiptMap to
            // limit this Firebase query?)
            return firebase.database().ref('receipts').once('value').then(receipts => {
                // Filter out the irrelevant receipts (again, Firebase perhaps could do that for us?)
                // and then map the remaining ones to objects with the desired information
                return receipts.filter(receipt => receiptMap.has(receipt.key)).map(receipt => {
                    const branchDetail = receipt.val().branch;
                    const branchName = branchDetail.branchName;
                    const branchAddress = branchDetail.branchAddress;
                    console.log(branchName + ' ' + branchAddress + ' ' + receipt.total);
                    return {branchName, branchAddress, total: receipt.total};
                });
            });
        }); 
    }); 

promiseDataList.then(arr => {
    console.log('promise done');
    for (var i = 0; i < arr.length; i++) {
        console.log(arr[i].branchName + ' ' + arr[i].branchAddress + ' ' + arr[i].total);
    }
});

这可以用箭头函数的简明形式编写得更简洁一些,但这有时会妨碍清晰。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45435530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档