Here is an example of a working code:
request('http://foo.com/')
// Collect list of locations.
.then(function (response) {
let $ = response.data,
locations = [];
$('a[href^="/venues/"]').each(function () {
locations.push({
name: $(this).text(),
url: 'http://foo.com/' + $(this).attr('href')
});
});
return locations;
})
// Retrieve additional information about locations.
.map((location) => {
return request(location.url)
.then((response) => {
// Combine location specific information with the initial location information.
response;
location;
});
}, {
concurrency: 5
});
In the above example, I am making a request to "foo.com", get a list of locations, then use location data to query "foo.com" for additional information about the location. At the end, I combine the location specific information with the initial location information.
What I do not like about the above the above code is that it is not flat. If location specific query would require additional async information and it child would require even more additional async information, the code would turn into a callback hell.
I would like to turn the code into a flat structure, e.g. (pseudo-code)
request('http://foo.com/')
// Collect list of locations.
.then(function (response) {
let $ = response.data,
locations = [];
$('a[href^="/venues/"]').each(function () {
locations.push({
name: $(this).text(),
url: 'http://foo.com/' + $(this).attr('href')
});
});
return locations;
})
// Retrieve additional information about locations.
.map((location) => {
return request(location.url);
}, {
concurrency: 5
})
// Filter list of responses.
.filter((response) => {
return response.incomingMessage.statusCode === 200;
})
// Combine location specific information with the initial location information.
.map((response) => {
// How to access "location" and "response"?
});
What is the best way to achieve it?