Reputation: 33
I have a follow on question from this post: Chaining Requests using BlueBird/ Request-Promise
I am very new to promises, so please forgive the naïveté. I am successfully able to implement this code:
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.
});
But in my case, the particular urls are different every time. I would like to take my fresh array of URLs, construct the options object for each, and then rp( ).
When I literally construct an array like this one - var freshArray =[rp({Uri1 w/options}), rp({Uri2 w/options}), etc]
and stick it into the .all( ) above - no luck. I think the rp()'s are being implemented independent of the BPromise.all call?
How do I dynamically embed a constructed array of promises into the code above?
Upvotes: 1
Views: 226
Reputation: 707238
If you're using Bluebird and you have an arbitrary array you want to process in parallel with async operations, then you should use Bluebird's Promise.map()
as it is a shortcut precisely for that situation:
var requestOptionsArray = [{...}, {...}, {...}];
Promise.map(requestOptionsArray, function(item) {
return rp(item);
}).then(function(results) {
// all results here
}).catch(function(err) {
// error here
});
Promise.map()
is a shortcut for iterating an array, calling a promise producing function on each item in the array, accumulating all the promises and then calling Promise.all()
with all the promises. Instead of all those steps, it does all that for you in one step. The end result is an array of ordered results. The operations are all run in parallel.
You can use Promise.mapSeries()
if you want to serialize the operations. You can pass a {concurrency: 3}
option to Promise.map()
if you want to control how many requests are in flight at the same time (useful for not overwhelming a target server with too many requests at once or useful for avoiding some situations where you might get rate limited with too many requests at once).
Upvotes: 1
Reputation: 10187
I'm not really sure about what you want to do, but would
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.
});
work? If so, you can even shorten it using (url) => rp(someFunction(url))
inside the map
=== edit ===
(x) => y
is an es6 shorthand that is most of the time like function(x) { return y; }
(x) => { ... return y; }
is a similar shorthand that let you have intermediary variables.more on es6 on the internet :) like here
.map
is a function defined on arrays. It applies the function to each element, so [1, 2].map((x) => x + 1)
returns [2, 3]
So the code is like
var urls = [optionsForRequest1, optionsForRequest2];
var urlsWithOptions = [];
for (var k in urls) {
urlsWithOptions.push(someFunction(urls[k]));
}
BPromise.all(urlsWithOptions)
...
Upvotes: 1