【问题标题】:use await inside Array.map function在 Array.map 函数中使用 await
【发布时间】:2018-01-17 16:13:50
【问题描述】:

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

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"

【问题讨论】:

  • 这很可能不是async/await 的问题。您是否仅使用一位用户尝试过您的代码(没有映射 - 最简单的实现)并验证它是否有效?
  • @spicypumpkin 是的,尝试了单项,它可以按预期工作,但多项就不行

标签: javascript arrays node.js asynchronous nodemailer


【解决方案1】:

你不需要在你的例子中使用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);
    }
  }
}

【讨论】:

    【解决方案2】:

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

    假设我们的异步 sendMail(msg,cb) 函数在 0-250 毫秒内发送一封邮件。我们可以在 sendMessages 函数中承诺它(以防它不返回承诺),并在 .reduce() 中将承诺与 .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);

    【讨论】:

      猜你喜欢
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2020-12-12
      • 1970-01-01
      • 2022-01-27
      • 2020-07-29
      相关资源
      最近更新 更多