在 Array.map 函数中使用 await

use await inside Array.map function

在遍历数组之前我需要等待异步函数完成,我需要等待解析的异步函数如下:

static async sendEmail (from, to, subject, text) {
        return new Promise((resolve, reject) => {
            let message = {
                from,
                to,
                subject,
                text
            };
            AMMailing.transporter.sendMail(message, function (err, response) {
                if (err) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
    }

这是我在数组中迭代并尝试等待它在再次迭代之前解析的方式的代码:

static sendEmailInQueue (queue) {
        queue.map(async (person, index) => {
            console.log('sending email to: ', person.email);
            try {
                let success = await AMMailing.sendEmail(AMMailing.message.from, person.email, AMMailing.message.subject, AMMailing.message.text);
                if (success) {
                    console.log('email sent to: ', person.email);
                }
            } catch (err) {
                console.log(err);
            }
        });
    }

我的问题是:这一行 console.log('sending email to: ', person.email); 一直执行,然后 AMMailing.sendEmail() 函数开始记录它的结果

这是我在控制台中得到的输出:

sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
sending email to:  matheus.rezende10@gmail.com
{ Error: Hostname/IP doesn't match certificate's altnames: "Host: mail.appmasters.io. is not in the cert's altnames: DNS:*.sgcpanel.com, DNS:sgcpanel.com"

您不需要在示例中使用 map,它不会映射任何内容。您可以简单地使用 for 循环遍历您的数组以按顺序等待每个项目。例如:

static async sendEmailInQueue (queue) { // async method
  for (let i = 0; i < queue.length; i++) {
    try {
      // await sequentially
      let success = await AMMailing.sendEmail(/* ... */);
      if (success) {
        console.log('email sent to: ', person.email);
      }
    } catch (err) {
      console.log(err);
    }
  }
}

您可以始终使用初始值为 Promise.resove().reduce() 并对您承诺的异步任务进行排序。

假设我们的异步 sendMail(msg,cb) 函数在 0-250 毫秒内发送一封邮件。我们可以在我们的 sendMessages 函数中承诺它(如果它没有 return 承诺)并在 .reduce().[=17 中用 .then() 个阶段对承诺进行排序=]

function sendMail(msg, cb){
  setTimeout(cb, Math.random()*250, false, "message to: " + msg.to + " is sent");
}

function sendMessages(ms){

  function promisify(fun, ...args){
    return new Promise((v,x) => fun(...args, (err,data) => !!err ? x(err) : v(data)));
  }
  
  ms.reduce((p,m) => p.then(v => promisify(sendMail,m))
                      .then(v => console.log(v)), Promise.resolve());
}

var msgArray = [{from: "x", to: "John@yyz.com", subject: "", text:""},
                {from: "y", to: "Rose@ist.com", subject: "", text:""},
                {from: "z", to: "Mary@saw.com", subject: "", text:""}
               ];
               
sendMessages(msgArray);