Sohrab
Sohrab

Reputation: 1488

How to return a Promise Function in For loop?

I have a function (sendEmail) as you see here:

public async sendEmail (log: LogMessage): Promise<void> {
nodemailer.createTestAccount(async () => {
      return ServiceFactory.getSystemService().getNetworkPreferences().then(async (networkPreferences) => {
....

I want to use it in a for loop:

for (const log of logs) {
          const timestamp = moment(log.creationDate)
          const startTime = new Date(Date.now())
          if ((timestamp.diff(startTime)) >= rule.miliSecond && category.includes(log.category)) {

            return this.sendEmail(log)
          }
        }

I cannot delete "return this.sendEmail(log)", because the function returns Promise. But the loop works just one time and with the first log, it would be terminated. How can I use the function in this loop?

Upvotes: 0

Views: 610

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

You need to put all the promises in an array and create a promise that completes when all the sendEmail promises complete.

sendAll() {
    let allMails: Promise<void>[] = [];
    for (const log of logs) {
        const timestamp = moment(log.creationDate)
        const startTime = new Date(Date.now())
        if ((timestamp.diff(startTime)) >= rule.miliSecond && category.includes(log.category)) {

            allMails.push(this.sendEmail(log));
        }
    }
    return Promise.all(allMails);
}

The version above launches all the requests in parallel. If you want to run sendEmail sequentially you can use async/await to wait while an email is ent before you send the next:

async sendAll() : Promise<void>{
    for (const log of logs) {
        const timestamp = moment(log.creationDate)
        const startTime = new Date(Date.now())
        if ((timestamp.diff(startTime)) >= rule.miliSecond && category.includes(log.category)) {

            await this.sendEmail(log);
        }
    }
}

Upvotes: 3

Related Questions