当前位置: 首页 > 知识库问答 >
问题:

.然后Promise.all不执行

方增
2023-03-14

我正在使用firestore检索具有以下DS的数据
我有一个公司集合,其中包含一个子集合Branchs
因此我试图检索以列出所有公司及其分支

代码:

exports.findAll = function (req, res) {
    getcompanies().
    then((companies) => {
        console.log("Main "+ companies) // info: Main TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
        return res.json(companies);
    })
    .catch((err) => {
        console.log('Error getting documents', err);
    });
}

function getCompanies(){
    var companiesRef = db.collection('companies');

    return companiesRef.get()
    .then((snapshot) => {
        let companies = [];
        return Promise.all(
            snapshot.forEach(doc => {  
                    let company = {};                
                    company.id = doc.id;
                    company.company = doc.data(); 
                    var branchesPromise = getBranchesForCompanyById(company.id);
                    return branchesPromise.then((branches) => {                    
                            company.branches = branches;
                            companies.push(company); 
                            if(snapshot.size === companies.length){
                                console.log("companies - Inside" + JSON.stringify(companies)); //This prints all companies with its branches
                            }
                            return Promise.resolve(companies);
                        })
                        .catch(err => {
                            console.log("Error getting sub-collection documents", err);
                            return Promise.reject(err);
                        }) 
            })
        )
        .then(companies => {
            console.log("Outside " + companies) // This is never executed 
            return companies;
        })
        .catch(err => {
            return err;
        });

    })
    .catch(err => {
        return err;
    });
}

function getBranchesForCompanyById(id){
    var branchesRef = db.collection('companies').doc(id).collection('branches');
    let branches = [];
    return branchesRef.get()
     .then(snapshot => {
        snapshot.forEach(brnch => {
            let branch = {};
            branch.id = brnch.id;
            branch.branch = brnch.data();
            branches.push(branch);
        })
        return branches;
    })
    .catch(err => {
        return err;
    })

 }

我已经得到了所有需要的数据。

console.log("companies - Inside" + JSON.stringify(companies)); //This prints all companies with its branches

但那时的promise。一切都不会被执行。所以得到这个错误-

无法读取未定义的属性符号(Symbol.iterator)

console.log("Main "+ companies) // info: Main TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

我觉得我已经遵守了这里规定的所有规则:https://stackoverflow.com/a/31414472/2114024关于嵌套promise,我不确定我在哪里遗漏了要点<提前谢谢!

共有3个答案

艾俊晖
2023-03-14

基于埃弗特和拉胡尔的意见,多亏了你们,我在这里解决了这个问题。

  1. 我处理了catch块中的所有错误
  2. 答应我。一切都没有返回任何东西,所以我将forEach转换为map

这是我更新的代码,它解决了这个问题:

exports.findAll = function (req, res) {
    getcompanies().
        then((companies) => {
            console.log("Main " + companies) // Prints all companies with its branches
            return res.json(companies);
        })
        .catch((err) => {
            console.log('Error getting documents', err);
            return res.status(500).json({ message: "Error getting the all companies" + err });
        });
}

function getCompanies() {
    var companiesRef = db.collection('companies');

    return companiesRef.get()
        .then((snapshot) => {
            let companies = [];
            return Promise.all(
                snapshot.docs.map(doc => {
                    let company = {};
                    company.id = doc.id;
                    company.company = doc.data();
                    var branchesPromise = getBranchesForCompanyById(company.id);
                    return branchesPromise.then((branches) => {
                        company.branches = branches;
                        companies.push(company);
                        if (snapshot.size === companies.length) {
                            console.log("companies - Inside" + JSON.stringify(companies));
                            return companies;
                        }
                    })
                        .catch(err => {
                            console.log("Error getting sub-collection documents", err);
                            throw new Error(err);
                        })
                })
            )
                .then(companies => {
                    console.log("Outside " + companies); // Executed now
                    return companies[companies.length - 1];
                })
                .catch(err => {
                    throw new Error(err);
                });

        })
        .catch(err => {
            throw new Error(err);
        });
}

function getBranchesForCompanyById(id) {
    var branchesRef = db.collection('companies').doc(id).collection('branches');
    let branches = [];
    return branchesRef.get()
        .then(snapshot => {
            snapshot.forEach(brnch => {
                let branch = {};
                branch.id = brnch.id;
                branch.branch = brnch.data();
                branches.push(branch);
            })
            return branches;
        })
        .catch(err => {
            throw new Error(err);
        })

}
岳阳文
2023-03-14

在代码中,可以使用map而不是forEach。许诺全部接受promise数组,但forEach不返回数组

return Promise.all(
    snapshot.map(doc => {
        let company = {};
        company.id = doc.id;
        company.company = doc.data();
        var branchesPromise = getBranchesForCompanyById(company.id);
        return branchesPromise.then((branches) => {
                company.branches = branches;
                companies.push(company);
                if (snapshot.size === companies.length) {
                    console.log("companies - Inside" + JSON.stringify(companies)); //This prints all companies with its branches
                }
                return Promise.resolve(companies);
            })
            .catch(err => {
                console.log("Error getting sub-collection documents", err);
                return Promise.reject(err);
            })
    })
)
关苗宣
2023-03-14

我发现至少有两个问题:

  • foreach可能不会返回任何内容,并且您将foreach的结果发送到Promise.all()
  • 如果Promise.all()抛出一个异常,一些catch处理程序只捕获错误并返回它。返回它将它变成一个非例外。

您实际上也不必向每个promise链添加一个catch,只要您将一个promise链的结果反馈给另一个promise链,您可能只需要一个catch块。

还有一个then()函数不应该嵌套得太深。把它提高一个层次,这就是promise的意义。

 类似资料:
  • 更新了问题和图像。 是否有任何方法可以暂停所有线程,直到任何线程执行samplerA为止(不管线程数是多少,这只需要执行一次),在执行这个sampler之后,所有线程都可以继续执行。单击以获取图像

  • 我最近开始使用php和mysql数据库构建一个登录系统。现在,我已经使用php代码和用户在引导模式中键入的数据构建了这个功能。 用户打开自己的邮箱,点击数据库中执行验证脚本的链接,将用户设置为已验证,并加载我的主站点页面。 之后,我想添加一些模态,告诉一些像“您的帐户已验证”只是一次。什么是正确的方法?我以为php可以通过运行位于中的jquery函数来完成 但正如我所看到的那样,这是不正确的,ph

  • 下面的函数不能像我希望的那样工作;作为一个JS新手,我不明白为什么。 我需要它等待5秒钟,然后检查是否为。 目前,它不等待,只是立即检查。

  • 问题内容: 我有多个ajax查询同时运行,我希望它们等待最后一个返回,然后在所有ajax调用上运行成功处理程序。作为简化示例,请考虑: 假设所有请求都同时发送。由于它们是异步的,因此它们将在不同的时间返回。假设一个请求返回需要100毫秒,而另一个请求则需要3000毫秒。我显然不知道哪个会最先返回。他们都以某种方式更新了DOM,我希望一次将这些更改一次全部显示给查看器。我该怎么做呢? 我能想到的最好

  • 原文是这样的: 这确实令人惊讶,但最终明白了(嗯,至少我想我明白了)为什么会这样发生。 现在,我将第二个更改为: 如果我遗漏了一些明显的东西,或者我的问题是愚蠢的,让我提前说声对不起。还有谢谢你!

  • 问题内容: 我正在尝试为UIImageView设置动画,然后在动画完成后隐藏图像视图。但是,在动画完成之前imageview被隐藏了。我看过类似的问题,他们建议在完成后在动画代码中实现动画侦听器或执行.hidden代码,但是我不确定如何在下面的shockView()函数中影响此效果。 仅在动画完成后,如何显示摇动动画并隐藏图像视图? 使用以下代码调用动画: 动画功能本身如下所示: 问题答案: 动画

  • 问题内容: 我通过Rabbitmq消息系统获得了。在发送之前, 我使用,将结果转换为并通过Rabbitmq发送。 我转换和发送的结构可以是:(更改了结构的名称和大小,但这没有关系) 要么 消息完全像a一样经过,并打印在另一面(某些服务器) 到目前为止,一切正常。现在,我试图将它们转换回它们的结构并声明类型。 第一次尝试是通过: 这是行不通的。当在拆封后打印它的类型时,我得到(?!?) 甚至比这更奇

  • 如代码所示,fileupload调用一个方法,该方法将文件保存在列表中 谢谢你的帮助。