Reputation: 4328
I'm trying to return promises from a promise and run Promise.all
like this:
updateVideos()
.then(videos => {
return videos.map(video => updateUrl({ id: video, url: "http://..." }))
})
.then(Promise.all) // throw Promise.all called on non-object
How can I use this kind of Promise.all
. I know .then(promises => Promise.all(promises))
works. But, just trying to know why that failed.
This happens with Express res.json
too. The error message is different, but I think the reason is same.
For example:
promise().then(res.json) // Cannot read property 'app' of undefined
does not work but
promise().then(results =>res.json(results))
does.
Upvotes: 9
Views: 2095
Reputation: 69
TJ Crowder's response explained why this happens. But if you are looking for a different solution, BluebirdJS (an npm promise library) handles this situation a bit differently. The following code works fine for me.
Using bluebird can also be helpful for dealing with promises that need to be executed and evaluated sequentially. mapSeries
has been a life-saver for me.
import * as Promise from "bluebird"
// ...
Promise.resolve()
.then(() => arrayOfPromises)
.then(Promise.all)
Upvotes: 0
Reputation: 1074425
all
needs to be called with this
referring to Promise
(or a subclass), so you'd need:
.then(promises => Promise.all(promises))
or
.then(Promise.all.bind(Promise))
It's important because all
needs to work correctly when inherited in Promise subclasses. For instance, if I do:
class MyPromise extends Promise {
}
...then the promise created by MyPromise.all
should be created by MyPromise
, not Promise
. So all
uses this
. Example:
class MyPromise extends Promise {
constructor(...args) {
console.log("MyPromise constructor called");
super(...args);
}
}
console.log("Creating two generic promises");
const p1 = Promise.resolve("a");
const p2 = Promise.resolve("a");
console.log("Using MyPromise.all:");
const allp = MyPromise.all([p1, p2]);
console.log("Using then on the result:");
allp.then(results => {
console.log(results);
});
.as-console-wrapper {
max-height: 100% !important;
}
Details in the spec. (Which I'm going to have to re-read in order to understand why five calls to MyPromise
are made when I call MyPromise.all
in the above.)
Upvotes: 17