Array Of Promise With Results Separately
Solution 1:
Just use map
:
letread = file => returnnewPromise(resolve => {
const fr = newFileReader();
fr.onload = e =>resolve(e.target.result);
fr.readAsDataURL(file);
});
Promise.all(files.map(file =>read(file).then(bar)))
.then(allResultsFromBar => { /* use results array */ });
Note that .then
promotes anything returned from a function it executes to a promise (i.e. it calls Promise.resolve
on it implicitly), so Promise.all
is guaranteed to receive an array of promises no matter what bar
returns.
Solution 2:
Working from @jib's answer and the comment :
I want to have a function readFiles that takes a list of files as its only argument, and I want it to return some kind of promise that I could call then() on, and the function that I would put in then() would be called separately for each of the files.
That's not quite possible because a .then()
callback is only called once, not once per result delivered by Promise.all()
.
This is close :
letread = file => returnnewPromise((resolve, reject) => {
const fr = newFileReader();
fr.onload = e =>resolve(e.target.result);
fr.onerror = reject; // don't forget to reject on error
fr.readAsDataURL(file);
});
letreadFiles = files => returnPromise.all(files.map(read)); // <<<<< this is the line you seek
Allowing you to write :
const files = ["...", "...", "..."];
readFiles(files)
.then(allFileResults => allFileResults.map(bar)); // bar is your function for processing file results// possibly chain another .then() if required to observe/process bar()'s results
Thus bar()
will operate on each of the file contents in turn.
However, in getting the code as close as possible to what you asked for :
- your "as soon as" requirement isn't truly meet; the
allFileContents.map(bar)
process is downstream ofPromise.all()
, therefore waits for all files to be read before commencing thebar()
calls. - any single error in
readFiles(...)
will (without some sort of error recovery) scupper the whole enterprise;allFileContents.map(bar)
would never be called on any of the files; that may be good or bad depending on your application; good news though, error recover is easily inserted. - as written,
bar()
must be synchronous; if not, you can simply insert anotherPromise.all()
, ieallFileResults => Promise.all(allFileResults.map(bar))
.
For these reasons, @jib's solution may well be the one to go for but it depends on what the application demands.
Post a Comment for "Array Of Promise With Results Separately"