Reputation: 5767
This question is the same as
How can I fetch an array of URLs with Promise.all? except that I want an answer that
does not use Promise.all
.
1
The array of URLs:
urls = ['https://jsonplaceholder.typicode.com/todos/2',
'https://jsonplaceholder.typicode.com/todos/3']
The JSONs of the URLs:
{"userId":1,"id":2,"title":"quis ut nam facilis et officia qui",
"completed":false}
{"userId":1,"id":3,"title":"fugiat veniam minus","completed":false}
The goal is to get an array of objects, where each object contains the title
value from the corresponding URL.
To make it a little more interesting, I will assume that there is already an array of names that I want the array of titles to be merged with:
namesonly = ['two', 'three']
The desired output is an array of objects:
[{"name":"two","loremipsum":"quis ut nam facilis et officia qui"},
{"name":"three","loremipsum":"fugiat veniam minus"}]
where I have changed the attribute name title
to loremipsum
.
1 The specific reason I want a solution not using Promise.all
is that I want JavaScript code that works in Postman scripts.
The latter don't (yet) support promises natively, at the time of writing.
Upvotes: 1
Views: 278
Reputation: 5767
The following solution relies on the second Stack Snippet of this helpful answer. 1
const namesonly = ['two', 'three'];
const urls = ['https://jsonplaceholder.typicode.com/todos/2',
'https://jsonplaceholder.typicode.com/todos/3'];
const titles = [];
let countDown = urls.length;
urls.forEach((url, index) => {
asynchronousCall(url, title => {
titles[index] = title;
if (--countDown === 0) { // Callback for ALL starts on next line.
const names = namesonly.map(value => ({ name: value }));
const fakeLatins = titles.map(value => ({ loremipsum: value }));
const result =
names.map((item, i) => Object.assign({}, item, fakeLatins[i]));
console.log('result:\n' + JSON.stringify(result));
}
});
});
function asynchronousCall (url, callback) {
console.log('Starting fetch for "' + url + '".');
fetch(url).then(response => response.json()).then(responseBody => {
console.log(url.slice(-1) + ': ' + responseBody.title + ' ...');
console.log('... fetch for ' + url + ' completed!');
callback(responseBody.title); // Individual callback.
});
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 I have deliberately left a lot of printouts in the code. The purpose is to make it easier to see what is happening and in what order. Anyone considering to use the code should of course remove some or all of the printouts.
Upvotes: 2