2017-06-30 2 views
4

Ich erstelle ein Skript in node.js (V8.1.3), die ähnliche JSON-Daten aus mehreren APIs untersucht und die Werte vergleicht. Um genauer zu sein, betrachte ich verschiedene Marktpreise verschiedener Aktien (eigentlich Kryptowährungen).Funktion ähnlich Promise.some/any für eine unbekannte Menge von Versprechen

Momentan verwende ich provect.all, um auf alle Antworten der entsprechenden APIs zu warten.

Allerdings gibt Promise.all einen Fehler aus, wenn sogar nur eine einzige Zusage mit einem Fehler abgewiesen wird. In den Bluebird-Docos gibt es eine Funktion namens Promise.some, die fast das ist, was ich will. Wie ich es verstehe, braucht es eine Reihe von Versprechen und löst die beiden schnellsten Versprechen zu lösen, oder sonst (wenn weniger als 2 Versprechen lösen) einen Fehler auslöst.

Das Problem dabei ist, dass erstens, ich entschlossen nicht die schnellsten zwei Versprechen sein will, was es gibt, ich keine erfolgreichen Versprechen will zurückgeführt werden, solange es mehr als 2. Dies scheint zu sein, was Promise.any macht, außer mit einer min count von 1. (Ich benötige eine Mindestanzahl von 2)

Zweitens weiß ich nicht, wie viele Promises ich erwarten werde (mit anderen Worten, I weiß nicht, wie viele APIs ich Daten von anfordern werde). Es können nur 2 oder 30 sein. Dies hängt von der Benutzereingabe ab.

Derzeit scheint es mir, es ist wahrscheinlich nur ein Weg, ein Versprechen zu haben. Alle mit einer Zählung von 2 und das wäre die einfachste Lösung. Ist das möglich?

Btw, nicht sicher, ob der Titel wirklich die Frage zusammenfasst. Bitte eine Änderung für den Titel vorschlagen :)

EDIT: Eine andere Möglichkeit, die ich das Skript schreibe ist, dass die ersten beiden APIs in geladen werden beginnen, berechnet und an den Browser und dann jedes nächste JSON geladen wird geladen und berechnet danach. Auf diese Weise warte ich nicht darauf, dass alle Versprechen erfüllt werden, bevor ich anfange, die Daten zu berechnen und die Ergebnisse an das Frontend zu übergeben. Wäre das mit einer Funktion möglich, die auch für die anderen Umstände funktioniert?

Was ich meine Art sieht aus wie folgt aus:

Anfordern von JSON parallel ...

| ----- JSON1 ------ |

| --- JSON-FAILS --- | > catch error> etwas mit Fehler machen. Wirkt sich nicht auf die nächsten Ergebnisse aus.

| ------- JSON2 ------- | > Erfüllt mindestens 2 Ergebnisse> berechnet JSON> zum Browser.

| ------- JSON3 --------- | > berechnet JSON> zum Browser.

+1

Sie können nur '.forEach()' das generierte Array von Versprechen und '.then()' jeder einzeln? –

Antwort

2

Wie wäre es mit then alle Versprechungen, so dass keine fehlschlagen, übergeben Sie das an Promise.all, und filtern Sie die erfolgreichen Ergebnisse in einem endgültigen .then.

Etwas wie folgt aus:

function some(promises, count = 1){ 

    const wrapped = promises.map(promise => promise.then(value => ({ success: true, value }),() => ({ success: false }))); 
    return Promise.all(wrapped).then(function(results){ 
     const successful = results.filter(result => result.success); 
     if(successful.length < count) 
     throw new Error("Only " + successful.length + " resolved.") 
     return successful.map(result => result.value); 
    }); 

} 
1

Dies könnte etwas klobig sein, wenn man bedenkt Sie ein Anti-Muster zu implementieren sind gefragt, aber Sie können jede lösen versprechen Kraft:

async function fetchAllJSON(settingsArray) { 
    let fetchedJSON = await Promise.all(
    settingsArray.map((settings) => { 
     // force rejected ajax to always resolve 
     return getJSON(settings).then((data) => { 
     // initial processing 
     return { success: true, data } 
     }).catch((error) => { 
     // error handling 
     return { success, false, error } 
     }) 
    }) 
).then((unfilteredArray) => { 
    // only keep successful promises 
    return dataArray.filter(({ success }) => success) 
    }) 
    // do the rest of your processing here 
    // with fetchedJSON containing array of data 
} 
+0

Ich repariere, was ich dachte, könnte den Downvote verursachen. War das Verpacken mit 'neuem Versprechen (...)' das Problem? –

+0

sollte es nicht sein lassen geholtJSON = erwarten Promise.all (... '? –

+0

@TamasHegedus ja, danke fürs Fangen, habe nicht gesehen. –

Verwandte Themen