Reputation: 895
If I have an array of promises, I can simply use Promise.all
to wait for them all.
But when I have an array of objects, each of them having some properties that are promises, is there a good way to deal with it?
Example:
const files=urlOfFiles.map(url=>({
data: fetch(url).then(r=>r.blob()),
name: url.split('/').pop()
}))
//what to do here to convert each file.data to blob?
//like Promise.all(files,'data') or something else
Upvotes: 6
Views: 2815
Reputation: 39270
With multiple async properties of the return value you could use nested Promise.all
(if other async results rely on response of fetch
) or as Tulir suggested; start off with a Promise.all([fetch(url),other])...
:
Promise.all(
urlOfFiles.map(
url=>
fetch(url)
.then(
r=>
Promise.all([//return multiple async and sync results
r.blob(),
Promise.resolve("Other async"),
url.split('/').pop()
])
)
.then(
([data,other,name])=>({//return the object
data,
other,
name
})
)
)
)
.then(
files=>
console.log("files:",files)
);
Upvotes: 1
Reputation: 928
Instead of mapping the data to an array of objects, you could map it to an array of promises that resolve to objects:
const promises = urlOfFiles
.map(url => fetch(url)
// r.blob() returns a promise, so resolve that first.
.then(r => r.blob())
// Wrap object in parentheses to tell the parser that it is an
// object literal rather than a function body.
.then(blob => ({
data: blob,
name: url.split('/').pop()
})))
Promise.all(promises).then(files => /* Use fetched files */)
Upvotes: 10
Reputation: 12890
Try something like this:
const files = urlOfFiles.map(url=>
fetch(url).then(r=> ({
data: r.blob()
name: url.split('/').pop()
})
))
Promise.all(files)
Upvotes: 1