I want to fetch
multiple JSON files. Here's my code:
var timestamps = [];
var urls = ['assets/layouts/default.json','assets/layouts/simple.json'];
var jsons = [];
Promise.all(urls.map(url => {
fetch(url)
.then(data => data.json())
.then(json => {
jsons.push(json);
timestamps.push(performance.now());
});
}))
.then(() => {
console.log(`All assets loaded. Assets were loaded at: ${timestamps}, this log was made at ${performance.now()}. Loaded data: ${jsons}`);
}
);
The problem is that the Promise.all
seems to resolve prematurely. As you can see I included some debugging, it logs this:
All assets loaded. Assets were loaded at: , this log was made at 37.73. Loaded data:
If I wrap that console.log
in a setTimeout
and save the time when Promise.all
is resolved like so:
.then(() => {
let promiseResolvedAt = performance.now();
setTimeout(() => {
console.log(`All assets loaded. Assets were loaded at: ${timestamps}, Promise.all was resolved at ${promiseResolvedAt}. Loaded data: ${jsons}`);
})
}
I get this:
All assets loaded. Assets were loaded at: 63.44000000000001,63.555, Promise.all was resolved at 55.96500000000001. Loaded data: [object Object],[object Object]
I can get it to work like I want it to by using setTimeout
but I'm sure there is a better way and I'm just doing something wrong here.
Why does the Promise.all
resolve before it's component promises resolve?
I'm running this on Chrome 55.
You need to return the promise:
Promise.all(urls.map(url => {
return fetch(url)
.then(data => data.json())
.then(json => {
jsons.push(json);
timestamps.push(performance.now());
});
}))
Arrow functions can have either a "concise body" or the usual "block body".
In a concise body, only an expression is needed, and an implicit return is attached. In a block body, you must use an explicit
return
statement.