我正在尝试从承诺中返回承诺并运行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))
确实
答案 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)