javascript - 如何推送到异步任务中的列表并仅在异步任务完成后才返回列表?

标签 javascript node.js mongoose

我在返回列表时遇到问题。首先,我通过查询数据库将元素添加到列表中,一旦数据库查询完成,我就只返回列表。但是,我意识到查询是异步发生的,这段代码在完成查询所有数据并将其添加到列表之前就返回了。

我知道在其他语言中,我们可以使用 Mutex 或 Semaphore 来解决这个竞争条件问题,但我们如何在 Javascript 中处理这个问题?

    let all_recipe= []
        for(let i =0; i<result.chefs.email.length; ++i)
        {

            chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe")
            .then(recipes=>{
                if(recipes!=null)
                {

                    if(recipes.recipe.length!=0)
                    {
                        all_recipe.push(recipes.recipe);
                    }

                }
                            console.log("Async Test1")
            }).catch(err=>
            {

                console.log(err);
                return res.status(500).json({
                    message:"Finding Chef Database Error!",
                    error: err
                });
            });

        }
        console.log("Async Test2")
        console.log(all_recipe);
        return res.status(200).json(all_recipe);

调试控制台输出:

Async Test2
[]
GET /store/ABC%20Pizza%20Store/getAllMenu 200 179.642 ms - 2
Async Test1
Async Test1
Async Test1

解决方案 添加异步/等待 promise :

storeSchema.findOne(req.params,"chefs").exec()
.then(async result=>{
    if(result.length<1)
    {

        return res.status(409).json({
            error_code:20,
            message:"Store not registered by Manager yet"
        });
    }
    else
    {

        let all_recipe= []
        for(let i =0; i<result.chefs.email.length; ++i)
        {
            try{


                let recipes = await chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe").exec();
                if(recipes!=null)
                {

                    if(recipes.recipe.length!=0)
                    {
                        all_recipe.push(recipes.recipe);
                    }

                }
            }
            catch(err)
            {
                return res.status(500).json({
                message:"getAllMenu Database Error!"
                });
            }

        }
        console.log("Async Test2")
        console.log(all_recipe);
        return res.status(200).json(all_recipe);

最佳答案

备选方案之一是在将结果记录到控制台之前引入关键字 await。它实际上会让 JavaScript 等待,直到 findOne 返回的 promise 完成并返回其结果。

使用这个link供引用。

我认为以下应该可行:

let all_recipe= []
    for(let i =0; i<result.chefs.email.length; ++i)
    {

        await chefSchema['chef'].findOne({"email":result.chefs.email[i]},"recipe")
        .then(recipes=>{
            if(recipes!=null)
            {

                if(recipes.recipe.length!=0)
                {
                    all_recipe.push(recipes.recipe);
                }

            }
                        console.log("Async Test1")
        }).catch(err=>
        {

            console.log(err);
            return res.status(500).json({
                message:"Finding Chef Database Error!",
                error: err
            });
        });

    }
    console.log("Async Test2")
    console.log(all_recipe);
    return res.status(200).json(all_recipe);

关于javascript - 如何推送到异步任务中的列表并仅在异步任务完成后才返回列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49615904/

相关文章:

javascript - 如何调整 WebDriverJS 浏览器窗口的大小?

javascript - 使用 ES6 保存函数 mongoose

javascript - 如何使用自定义日期格式的 find() 方法从集合中检索数据

javascript - Facebook - 无效范围 : manage_pages

javascript - 从内存中删除旧模型

node.js - Backbone.js、mongodb 和获取相关对象 - 客户端还是服务器端?

mongodb - 为什么这个 Node.js 插件 Mongoose 不起作用?我遵循了所有指示

javascript - ajax调用后如何重新加载脚本?

javascript - Twig 和javascript

json - 获取 null,$sum 聚合 - Mongo