2017-08-09 70 views
1

我需要等待一個異步函數來遍歷數組超過前完成內等待,異步函數,我需要等待解決如下:使用Array.map功能

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: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
sending email to: [email protected] 
{ 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" 
+0

這是最有可能不能以'異步/ await'的問題。你是否只用一個用戶試過了你的代碼(沒有映射 - 最簡單的可能實現),並驗證它的工作原理? – spicypumpkin

+0

@spicypumpkin是用單一條目試過的,它的工作方式和預期的一樣,但是它並不是 –

回答

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); 
    } 
    } 
} 
+0

實際上它工作正常,謝謝! –

0

您可以隨時使用.reduce()Promise.resove()初始值和順序您promisified異步任務。

假設我們的異步sendMail(msg,cb)函數在0-250ms內發送郵件。我們可能會在我們的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: "[email protected]", subject: "", text:""}, 
 
       {from: "y", to: "[email protected]", subject: "", text:""}, 
 
       {from: "z", to: "[email protected]", subject: "", text:""} 
 
       ]; 
 
       
 
sendMessages(msgArray);