3

How can I use async/await inside a for loop?

This is my code:

export default (req, callback) => {
  // ...
  compliance.forEach((rule, index) => {
    let response = await waRuleOverview(req, run.id, rule.id);
    // handle the response
  });
}

This is how I define the waRuleOverview function:

export function waRuleOverview(req, runId, ruleId) {
  var def = deferred();

  setTimeout(function() {
    const apiToken = req.currentUser.apiToken;
    const payload = {
      'Authorization': 'api_key ' + apiToken
    }

    const options = {
      'method': 'get',
      'gzip': true,
      'headers': payload,
      'content-type': 'application/json',
      'json': true,
      'url': 'api-url'
    }

    request(options, (error, response, body) => {
      def.resolve(body);
    });
  }, 50);

  return def.promise;
}

It throws this error in the console:

await is a reserved word

This question is related to this one which I'm trying to figure out how to solve it.

Valip
  • 4,440
  • 19
  • 79
  • 150

1 Answers1

15

It depends on how you want your async code to be executed: sequentially or in parallel. Anyway, you'd need to add async keyword to use await.

// sequential
export default async (req, callback) => {
  // ...
  for(const [rule, index] of compliance.entries()) {
    const response = await waRuleOverview(req, run.id, rule.id)

    // handle the response
  }
}

// parallel
export default async (req, callback) => {
  // ...
  const responses = await Promise.all(compliance
     .map((rule, index) => waRuleOverview(req, run.id, rule.id))
  )

  // handle responses
  responses.forEach(response => {
    // ...
    // handle response here
  })
}

And finally, if you don't really want your handler to return a Promise but just want it to perform some async actions for side effects.

export default (req, callback) => {
  // ...
  compliance.forEach(/* add */ async (rule, index) => {
    // to use await inside
    let response = await waRuleOverview(req, run.id, rule.id);
    // handle the response
  });
}

But this approach is actually an anti-pattern since it breaks promise chains: bad for composability, error handling and such.

Rowland
  • 1,728
  • 1
  • 12
  • 19
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98