【发布时间】:2020-02-08 08:09:21
【问题描述】:
我遇到了一些不寻常的行为。
基本上,作为我的代码的一部分,我有一个函数,它利用嵌套的 for 循环来构建一个 Promise 并将其添加到 Promise 列表中。
嵌套循环完成后,我想使用 promise.all() 评估承诺列表。
过去我已经成功地使用单个 forEach 循环来做到这一点,嵌套似乎会导致一些问题,即测试显示 Promise.all 在嵌套的 forEach 循环终止之前被调用,导致它被调用一个空列表,因此返回一个空列表。
我感觉问题在于我在嵌套的 forEach 循环中的某处缺少 return 语句,如 this answer 中所述,但我无法确定在哪里。
罪魁祸首.jsconst otherModule = require("blablabla")
const otherOtherModule = require("blablabla2")
function nestedFunction(list){
var promises = [];
list.forEach(element => {
otherModule.getSublist(element).then(sublist => {
sublist.forEach(subelement => {
promises.push(otherOtherModule.promiseResolvingFunction(subelement));
});
});
});
return Promise.all(promises);
}
module.exports = {
nestedFunction : nestedFunction
}
罪魁祸首.test.js
const culprit = require("culpritpath")
// for mocking
const otherModule = require("blablabla")
otherModule.getSublist = jest.fn(() => Promise.resolve([{}, {}, {}]))
const otherOtherModule = require("blablabla2")
otherOtherModule.promiseResolvingFunction = jest.fn(() => Promise.resolve())
describe("nestedFunction()", ()=>{
it("returns an array of resolved promises", () => {
return culprit.nestedFunction([{}, {}]).then(res => {
expect(res).toHaveLength(6);
})
})
})
相反,我知道res 是[]。进一步的测试表明 promiseResolvingFunction 被调用了正确的次数,据我所知,Promise.all 在嵌套的 forEach 循环完成之前被调用。
PS:我仍然开始使用 Promise 和 TDD,我很高兴听到有关任何代码异味的反馈。
【问题讨论】:
-
问题是您的
.push()调用嵌套在另一个承诺解决方案中。所以你的外部.forEach()在任何.then()s执行之前完成,当你将它传递给Promise.all()时你的promises数组仍然是空的 -
没错,
Promise.all(promises);在.then之外被调用。所以在.then甚至执行之前你已经在调用Promise.all -
大家好,谢谢,我选择了一个解决方案。请问为什么所有解决方案都选择
map而不是forEach?
标签: javascript node.js asynchronous promise jestjs