调用Promise.all抛出Promise.all调用非对象?

时间:2018-01-23 10:45:57

标签: javascript node.js promise

我正在尝试从承诺中返回承诺并运行Promise.all,如下所示:

updateVideos()
.then(videos => {
     return videos.map(video => updateUrl({ id: video, url: "http://..." }))
})
.then(Promise.all) // throw Promise.all called on non-object

我如何使用这种Promise.all。我知道.then(promises => Promise.all(promises))有效。但是,只是想知道为什么会失败。

Express res.json也会发生这种情况。错误信息不同,但我认为原因是一样的。

例如:

promise().then(res.json) // Cannot read property 'app' of undefined

不起作用,但

promise().then(results =>res.json(results))

确实

2 个答案:

答案 0 :(得分:6)

需要使用all引用this(或子类)来调用

Promise,因此您需要:

.then(promises => Promise.all(promises))

.then(Promise.all.bind(Promise))

这很重要,因为all在Promise子类中继承时需要正常工作。例如,如果我这样做:

class MyPromise extends Promise {
}

...然后MyPromise.all创建的承诺应由MyPromise创建,而不是Promise。因此all使用this。例如:



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;
}




the spec中的详细信息。 (当我在上面调用MyPromise时,为了理解为什么五个调用MyPromise.all的原因,我将不得不重新阅读。)

答案 1 :(得分:0)

TJ Crowder 的回应解释了为什么会发生这种情况。但是,如果您正在寻找不同的解决方案,BluebirdJS(一个 npm 承诺库)会以不同的方式处理这种情况。以下代码对我来说很好用。

使用 bluebird 还有助于处理需要按顺序执行和评估的承诺。 mapSeries 对我来说是救命稻草。

import * as Promise from "bluebird"

// ...

Promise.resolve()
  .then(() => arrayOfPromises)
  .then(Promise.all)