2017-04-27 2 views
1

Ich habe ein Array von Links, die ich den Inhalt mit mercury-client analysieren, und schieben Sie das Ergebnis in eine articles Array.Versprechen, über ein Array von Links zu iterieren, sie mit quecksilber-Client zu analysieren und den geparsten Inhalt in ein neues Array zu schieben

* parseLinks() { 
    const links  = yield this.getInboxMessages() // It will be ['link1', 'link2', ..., 'linkN'] 
    const articles = [] 

    return new Promise((resolve, reject) => { 
    for (let link of links) { 
     mercury.parse(link).then((data) => { 
     articles.push(data) 
     }) 
    } 

    resolve(articles) 
    }) 
} 

Ich verstehe nicht, was falsch ist, denn ich habe nur [] bekommen. Ich versuchte, die Promise in die for..of zu verschieben, aber das Ergebnis blieb gleich.

Durch Entfernen der Schleife und damit Parsing nur den ersten Index von links Array hatte ich keine Probleme, obwohl.

Antwort

6

Sie lösen zu früh auf, bevor articles jemals gefüllt wird.

Sie können Ihren gesamten return Block mit diesem ersetzen:

return Promise.all(links.map(link => mercury.parse(link))); 

, die nur ein aufgelösten Versprechen zurückkehren werden einmal pro Verbindung behandelt worden ist.

Wenn (und nur dann) die mercury.parse Funktion wird übergeben als bloße Funktionsreferenz bewältigen, ohne dass mercury als Variable this Kontext übergeben Sie weiter vereinfachen könnte:

return Promise.all(links.map(mercury.parse)); 
+0

Einfach und einfach. Vielen Dank. – mfgabriel92

+0

@JaromandaX Ich habe Ihren Vorschlag (mit dem entsprechenden Vorbehalt) zur Antwort hinzugefügt – Alnitak

1

Sie erhalten [] Artikel, weil Sie resolve(articles) sync'ly aufrufen, während Ihre for Schleife Daten dort async'ly schiebt. Anstatt data in Ihre Artikel zu pushen, drücken Sie mercury.parse(link) verspricht in ein Array. Sie werden mit einer Reihe von zu lösenden Quecksilber-Kundenversprechen enden. Sie können dann Promise.all für dieses Array verwenden und articles nur auflösen, wenn alle abhängigen Versprechen gelöst wurden.

0

können Sie erreichen, dass mit Array.prototype.reduce und Promise.all Kombination. Etwas wie unten.

function parseLinks() { 
    const links = [....] 

    return Promise.all(links.reduce((promises, link) => { 
    return promises.concat(mercury.parse(link)) 
    }, [])) 
} 

parseLinks().then(links => console.log(links)) 
Verwandte Themen