Home > Software engineering >  How to Await a Loop of Async Operations?
How to Await a Loop of Async Operations?

Time:03-23

I have a patch endpoint that takes a body of fields to update, iterates over each field, and updates the correct value. I want to do something send a response once all those things are done, but I do not know how to await a loop of operations. If it was a singular operation I could just add .then(), but that would not work in this case. What is an elegant solution to this?

Code:

const updateUser = (req, res) => {
    const db = mongoConnection.getDb();
    for (key in req.body) {
        db.collection('users').updateOne(
            {username: req.query.username},
            {$set: {[key]: req.body[key]}}
        )
    }
    // send response once for loop is done
}

CodePudding user response:

I think an easy answer would be hiding the for loop in an async function, then use it in the endpoint.

const updateUserField = async () =>
  db.collection("users").updateOne(
    {
      username: req.query.username,
    },
    {
      $set: { [key]: req.body[key] },
    }
  );


const updateUserEndpoint = (req, res) => {
   for (let field of req.body) {
      await updateUserField(field);
   }

   res.status(200).send('updated');
}

Then, for testing, you could wrap the endpoint with a function that injects the function itself:

const updateUserEndpoint = (userUpdateFunc) => userUpdateFunc(req, res);

This pattern is called dependency injection - when writing unit tests for the endpoint, you'd just replace userUpdateFunc with whatever mocked function you want to use. This removes the need to monkeypatch the function in the test.

  • Related