最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Calling Promise.all throws Promise.all called on non-object? - Stack Overflow

programmeradmin3浏览0评论

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.

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.

Share Improve this question edited Jan 23, 2018 at 10:58 Faizuddin Mohammed asked Jan 23, 2018 at 10:45 Faizuddin MohammedFaizuddin Mohammed 4,3286 gold badges32 silver badges54 bronze badges 1
  • 2 Promise.all uses context (this) as a constructor for a new promise it returns. – Yury Tarabanko Commented Jan 23, 2018 at 10:48
Add a ment  | 

2 Answers 2

Reset to default 17

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

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)
发布评论

评论列表(0)

  1. 暂无评论