2017-08-09 4 views
1

I warten müssen, für eine Async Funktion vor Iterieren über die Anordnung zu vervollständigen, die asynchrone Funktion i warten müssen, um zu lösen ist, wie folgt:Verwendung warten innen Array.map Funktion

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

Diese

ist der Code der Art, wie ich in dem Array bin iterieren und zu versuchen, zu warten, bis es zu lösen, bevor es wieder iteriert:

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

Mein Problem ist: diese Zeile console.log('sending email to: ', person.email); wird alle Zeiten ausgeführt und dann die AMMailing.sendEmail() Funktion starten ist es führt zu protokollieren

dies ist die Ausgabe i in der Konsole:

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

Dies ist höchstwahrscheinlich kein Problem mit 'async/await'. Haben Sie Ihren Code mit nur einem Benutzer ausprobiert (ohne Mapping - möglichst einfache Implementierung) und verifiziert, dass er funktioniert? – spicypumpkin

+0

@spicypumpkin ja versuchte es mit einem einzigen Eintrag und es funktioniert wie erwartet, aber mit mehreren es nicht –

Antwort

1

Sie müssen map in Ihrem Beispiel nicht verwenden, es wird nichts zugeordnet. Sie können einfach mit for-loop über Ihr Array iterieren, um nacheinander auf jedes Element zu warten. Zum Beispiel:

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

tatsächlich hat es funktioniert, danke! –

0

Sie können immer ein .reduce() mit einem Anfangswert von Promise.resove() verwenden und Ihre promisified asynchronen Aufgaben sequenzieren.

Nehmen Sie an, dass unsere asynchrone sendMail(msg,cb) Funktion eine Mail in 0-250ms sendet. Wir können es promiziieren (falls es kein Versprechen gibt) in unserer sendMessages Funktion und Reihenfolge die Versprechen mit Stufen innerhalb einer .reduce().

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);