2016-09-02 3 views
1

Ich habe eine Folge auf Frage von diesem Posten: Chaining Requests using BlueBird/ Request-PromiseDrossel Anfrage Funktion

Ich bin sehr neu auf Versprechungen, so wenden Sie sich bitte die Naivität vergeben. Ich bin erfolgreich in der Lage diesen Code zu implementieren:

var BPromise = require('bluebird'); 
var rp = require('request-promise'); 

BPromise.all([ 
    rp(optionsForRequest1), 
    rp(optionsForRequest2) 
]) 
.spread(function (responseRequest1, responseRequest2) { 
    // Proceed with other calls... 
}) 
.catch(function (err) { 
    // Will be called if at least one request fails. 
}); 

Aber in meinem Fall die besondere Urls verschieden ist, jedes Mal. Ich möchte meine neue Reihe von URLs nehmen, konstruiere das Optionsobjekt für jeden und dann rp().

Wenn ich buchstäblich ein Array wie dieses bauen - var freshArray =[rp({Uri1 w/options}), rp({Uri2 w/options}), etc] und stecken Sie es in die .all() oben - kein Glück. Ich denke, die RP() werden unabhängig von der BPromise.all Call implementiert?

Wie kann ich ein konstruiertes Array von Versprechen dynamisch in den obigen Code einbetten?

Antwort

1

Ich bin nicht wirklich sicher, was Sie tun wollen, aber würde

BPromise.all([optionsForRequest1, optionsForRequest2].map((url) => { 
    const urlWithOptions = someFunction(url); 
    return rp(urlWithOptions); 
})]) 
.spread(function (responseRequest1, responseRequest2) { 
    // Proceed with other calls... 
}) 
.catch(function (err) { 
    // Will be called if at least one request fails. 
}); 

Arbeit? Wenn ja, können Sie es sogar verkürzen mit (url) => rp(someFunction(url)) innerhalb der Karte

=== bearbeiten ===

  • (x) => y ist ein es6 Stenografie, die wie die meiste Zeit ist function(x) { return y; }
  • (x) => { ... return y; } wird ein ähnliches Kurzschrift, mit der Sie Zwischenvariablen haben können.
  • mehr auf es6 im Internet :) wie here

  • .map ist eine Funktion auf Arrays definiert. Es wendet die Funktion auf jedes Element, so [1, 2].map((x) => x + 1) kehrt [2, 3]

So ist der Code wie

ist
var urls = [optionsForRequest1, optionsForRequest2]; 
var urlsWithOptions = []; 
for (var k in urls) { 
    urlsWithOptions.push(someFunction(urls[k])); 
} 

BPromise.all(urlsWithOptions) 
... 
+0

Danke Guig! Das möchte ich tun. Kannst du mir helfen, ein bisschen mehr zu verstehen? Sollte das Optionsfeld ein Array von Objekten sein? Und sollte es die URL als einen der Parameter enthalten? Wie funktioniert das?map() weiß/bekomme die URL in .map (url)? Sorry, ich verstehe nicht, was das => in (url) => rp (someFunction (url)) bedeutet. – kaynew

+0

ok. Ich fügte einige Klarstellungen hinzu. Auch, Google ist dein bester Freund https://www.google.com/search?espv=2&biw=1440&bih=695&q=javascript+arrow+syntax – Guig

+0

Danke nochmal, Guig. Manchmal ist es überwältigend zu googeln, wenn ich total verloren bin, also schätze ich es sehr, dass du mich in die richtige Richtung gelenkt hast. Ich denke, ich verstehe es jetzt. DANKE! – kaynew

1

Wenn Sie Drossel verwenden, und Sie haben eine beliebige Array Sie parallel verarbeiten wollen mit Asynchron-Operationen, dann sollten Sie Bluebird verwenden Promise.map() als es eine Verknüpfung genau für diese Situation ist:

var requestOptionsArray = [{...}, {...}, {...}]; 
Promise.map(requestOptionsArray, function(item) { 
    return rp(item); 
}).then(function(results) { 
    // all results here 
}).catch(function(err) { 
    // error here 
}); 

Promise.map() ist eine Abkürzung für das Iterieren eines Arrays und ruft ein Versprechen auf, das Funktion für jedes Element im Array erzeugt, alle Versprechen sammelt und dann Promise.all() mit allen Versprechen aufruft. Statt all dieser Schritte macht es das alles für Sie in einem Schritt. Das Endergebnis ist eine Anordnung von geordneten Ergebnissen. Die Operationen werden alle parallel ausgeführt.

Sie können Promise.mapSeries() verwenden, wenn Sie die Operationen serialisieren möchten. Sie können eine {concurrency: 3} -Option an Promise.map() übergeben, wenn Sie steuern möchten, wie viele Anfragen gleichzeitig ausgeführt werden (nützlich, um einen Zielserver nicht mit zu vielen Anfragen auf einmal zu überlasten oder um einige Situationen zu vermeiden, in denen Sie mit der Rate eingeschränkt werden zu viele Anfragen auf einmal).

+0

Wenn Sie sagen "Die Vorgänge werden alle parallel ausgeführt", beziehen Sie sich auf eine asynchrone Anfrage, aber nicht auf die Zuordnung, richtig? – Guig

+0

@Guig - Korrekt. Die 'Promise.map()' läuft synchron und startet nacheinander alle asynchronen Operationen. Diese asynchronen Vorgänge sind alle gleichzeitig "in-flight". Wenn alle fertig sind (irgendwann später), wird der '.then()' Handler aufgerufen. – jfriend00