Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Promise.all throws Promise.all called on non-object?

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.

like image 611
Faizuddin Mohammed Avatar asked Jan 23 '18 10:01

Faizuddin Mohammed


People also ask

Does Promise all wait for all promises?

Promise.all waits for all fulfillments (or the first rejection).

What are the three states of a Promise?

A Promise is in one of these states: pending: initial state, neither fulfilled nor rejected. fulfilled: meaning that the operation was completed successfully. rejected: meaning that the operation failed.

Does Promise all run promises in parallel?

all doesn't guarantee you to run things in parallel. In fact, Promise. all is only reliable for waiting until all the promises passed to it are done. Its job is to ensure that no promises get passed until they are done with their job.

Does Promise all resolve promises in order?

Here, Promise. all() method is the order of the maintained promises. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.


1 Answers

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.)

like image 66
T.J. Crowder Avatar answered Sep 28 '22 09:09

T.J. Crowder