如何在 for 循环中运行 mongoose 方法,因为 mongoose 函数是异步的

Posted

技术标签:

【中文标题】如何在 for 循环中运行 mongoose 方法,因为 mongoose 函数是异步的【英文标题】:how to run mongoose method inside for loop, as mongoose function is asynchronous 【发布时间】:2020-02-16 07:32:26 【问题描述】:

我正在尝试运行 mongoose find 命令,如果它与数组中的少数数据集匹配,则需要更新数据库。 这是我写的查询。

membersId=["U-ZCIwZGvW", "U-MbyAVxXf", "U-Gbe9RhGu"];

let updateUserData=(groupData)=>
    return new Promise((resolve,reject)=>
        for(M in membersId)
            console.log(membersId[M]);
            UserModel.findOne(userId:membersId[M],(err,response)=>
                if(err)
                    console.log(err);
                    reject(err);
                else if(check.isEmpty(response))
                    reject("Id not found");
                else
                    if(!response.groups.includes(groupData._id))
                        response.groups.push(groupData._id)
                        response.save((err,data)=>
                        if(err)
                            console.log(err);
                            reject(err);
                        else
                         console.log(data);   
                        
                    )
                    
                
            )
        
        resolve(groupData,'Members Added','AddMembersToGroup',00);
    )

我读到了 async-await 并尝试了这个..

membersId=["U-ZCIwZGvW", "U-MbyAVxXf", "U-Gbe9RhGu"];

let updateUserData = (groupData) => 
    return new Promise((resolve, reject) => 

        async function getTodos() 
            for (const M of membersId) 
                    await UserModel.findOne( userId: M , (err, response) => 
                    if (err) 
                        console.log(err);
                        reject(err);
                     else if (check.isEmpty(response)) 
                        reject("Id not found");
                     else 
                        if (!response.groups.includes(groupData._id)) 
                            response.groups.push(groupData._id)
                            response.save((err, data) => 
                                if (err) 
                                    console.log(err);
                                    reject(err);
                                 else 
                                    console.log(data);
                                
                            )
                        
                    
                )
            

            console.log('Finished!');
            resolve(groupData,'Members Added','AddMembersToGroup',00);
          

          getTodos();
    )

async 方法正在工作,但它仍然不是完全同步的,而且如果出现任何错误,它也不会停止。

如何在出错时退出for循环并只执行一次resolve语句,以便它一旦运行就不会返回到其他代码。

即使有错误它也会运行。

【问题讨论】:

【参考方案1】:

有几点:

您不需要执行多个find 请求来查找和更新多条记录,只需使用updateMany 和正确的过滤器和更新参数 一个异步函数返回一个 Promise,而你的函数 getTodos 不是这样的情况@ 你需要像这样调用异步函数:await getTodos(); 如果你的 promise 拒绝了你需要在 try/catch 中处理的事情(抛出错误)

您可以在异步函数中使用以下内容:

try 
    var response = await getTodos(groupData, membersId);
    console.log(response);

catch(err)
    console.log(err);

使用getTodos 函数:

async function getTodos(groupData,membersId) 
    return new Promise(function(resolve, reject)
        UserModel.updateMany( 
            userId:  "$in" : membersId,
            groups:  "$ne": groupData._id 
        , 
            $push:  groups: groupData._id  
        , function(err,response)
            if (err) 
                reject(err);
             else if (response.nModified === 0)
                reject("Id not found");
             else 
                resolve(response.nModified + " items modified");
            
        );
    );

【讨论】:

以上是关于如何在 for 循环中运行 mongoose 方法,因为 mongoose 函数是异步的的主要内容,如果未能解决你的问题,请参考以下文章

Node.js/Mongoose 等待异步 For 循环

JAVA中的for循环运行一次后如何停止,但是还可以在输入数字后继续运行?

如何使代码在 FOR 循环中运行?而不是那么多的IF

JS中如何解决for循环中的延迟执行问题

在 R 中并行运行 for 循环

如何通过 android 中的回收器视图运行 for 循环?