2

I am trying to run a loop and performing async operation in it. I am trying to delete documents from Mongodb. I want the script to terminate when all delete operations completed. I tried using process.exit(0), but when I use this method to terminate the script, no number is getting deleted .

async function deletor() {
mobile_numbers.forEach(async (mobile_number) => {
    await db.collection(db_config.collectionName).remove(
    { mobile: mobile_number }
    )
})
}
deletor()
process.exit(0)

When all delete operations completed, then the script should terminate. but it terminates before the delete operation completes. I want to add this script to cron job, and I want to terminate the script when all the async operations are completed.

How can this be done?

7
  • Welcome to Stack Overflow! Please take the tour (you get a badge!), have a look around, and read through the help center, in particular How do I ask a good question? I also recommend Jon Skeet's Writing the Perfect Question and Question Checklist. Commented Dec 29, 2018 at 17:08
  • Node will do so automatically unless you do something to prevent it. What specific problem are you having? Commented Dec 29, 2018 at 17:08
  • I have modified the question, I am trying multiple async operation in a loop, i want to terminate the script when all the async operations are completed.. Commented Dec 29, 2018 at 17:22
  • Does db.collection.remove return a promise? Await will only work with functions that return promises. Commented Dec 29, 2018 at 17:22
  • No, i will try with returning with a promise Commented Dec 29, 2018 at 17:23

2 Answers 2

2

You've said that db.collection(...).remove(...) doesn't return a promise, but that you'll try one. Once you do:

forEach doesn't do anything with the return value of the callback, so it won't do anything to wait for the promises created by your async callback to settle.

Instead, to run them in parallel, use map and Promise.all:

await Promise.all(mobile_numbers.map(number => {
    return /*...create a promise for the remove operation here...*/;
}));

Example:

const removeNumber = number => new Promise(resolve => {
  console.log(`Removing ${number}...`);
  setTimeout(() => {
    console.log(`${number} removed`);
    resolve();
  }, Math.random() * 500);
});

async function deletor(mobile_numbers) {
    await Promise.all(mobile_numbers.map(number => {
        return removeNumber(number);
    }));
}

deletor(["111", "222", "333", "444", "555"])
    .then(() => { console.log("Done"); })
    .catch(err => { console.error("Error:", err); });

To run them in series, you can use the "Promise reduce" trick:

await mobile_numbers.reduce((p, number) => {
    return p.then(() => {
        return /*...create a promise for the remove operation here...*/
    });
}, Promise.resolve());

Example:

const removeNumber = number => new Promise(resolve => {
  console.log(`Removing ${number}...`);
  setTimeout(() => {
    console.log(`${number} removed`);
    resolve();
  }, Math.random() * 200);
});

async function deletor(mobile_numbers) {
    await mobile_numbers.reduce((p, number) => {
        return p.then(() => {
            return removeNumber(number);
        });
    }, Promise.resolve());
}

deletor(["111", "222", "333", "444", "555"])
    .then(() => { console.log("Done"); })
    .catch(err => { console.error("Error:", err); });

Sign up to request clarification or add additional context in comments.

1 Comment

Hi, thanks for the help, this code really worked!. you were right "forEach doesn't do anything with the return value of the callback, so it won't do anything to wait for the promises created by your async callback to settlel"
1

1) Try this code

deletor().then(() => process.exit(0));

Async function “deletor()” returns a promise. That means you can use a method “then()” executed after “deletor()”.

Another way is using async “main()” function

async function deletor() {...}
async function main() {
    await deletor();
    process.exit(0);
 }
 main();

2) Instead of “.forEach(async ...)” you should use either

Promise.all(...)

or

for (const item of items) {
   await .....
}

First case runs parallel. Second runs serial.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.