简体   繁体   中英

how to run mongoose method inside for loop, as mongoose function is asynchronous

I am trying to run an mongoose find command and if it matches few dataset in array, then need to update the database. here is the query i have written.

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);
    })
}

i read about async-await and tried this..

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();
    })
}

the async method is working, but still it is not fully synchronous, and also if any error occurs, it does not stop.

how to exit the for loop on error and do the resolve statement only once so that it does not go back to other code once run.

even if there is error it runs.

There are a few things:

  • you don't need to perform multiple find requests to find & update multiple records, just use updateMany with the right filter & update parameters
  • an async function return a Promise which is not the case of your function getTodos
  • you need to invoke the async function like this: await getTodos();
  • in case your promise rejects something you need to handle this in try/catch (error is thrown)

You can use the following inside an async function:

try {
    var response = await getTodos(groupData, membersId);
    console.log(response);
}
catch(err){
    console.log(err);
}

with the getTodos function:

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");
            }
        });
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM