我正在使用一些旧代码,并试图返回两个promise数组的结果。
所以主体基本上包含first
和second
,它们是id的数组。我知道下面的代码适用于一个由1到5个id组成的小数组,但如果我要做几百个,在我从两个promise数组中得到一百个结果之前,resolve会开火吗?
const doSomething = (body) => {
return new Promise((resolve, reject) => {
const promisesOne = body.first.map((id) =>
doSomethingOne(id)
);
const promisesTwo = body.second.map((id) =>
doSomethingTwo(id)
);
let response = {
first: {}
second: {}
headers: 'mock headers'
};
Promise.all(promisesOne).then((results) => {
response.first = results;
});
Promise.all(promisesTwo).then((results) => {
response.second = results;
});
resolve(response);
});
};
此外,我将无法将其重构为async/await,因为这个代码库没有使用它
在我得到。。。两个promise数组的结果?
是的,绝对是因为您没有等待它们解决。
只需将两个Promise.all()
承诺包装在另一个Promise.all()
中,等待所有内容,然后创建所需的最终对象。
const doSomething = (body) => {
return Promise.all([
Promise.all(body.first.map(doSomethingOne)),
Promise.all(body.second.map(doSomethingTwo)),
]).then(([first, second]) => ({
first,
second,
headers: "mock headers",
}));
};
您可以通过创建body
属性名称到其相应映射函数的映射来使其通用。例如
const mappers = {
first: doSomethingOne,
second: doSomethingTwo,
};
const doSomething = (body) => {
return Promise.all(
Object.entries(mappers).map(([key, mapper]) =>
Promise.all(body[key].map(mapper)).then((data) => ({ [key]: data }))
)
)
.then((results) => Object.assign({ headers: "mock headers" }, ...results));
};
您的代码目前无法工作-resolve(response)
将在任何一个Promise.all
完成之前运行。
首先,重构.first
和.second
(etc(属性,使它们成为数组,而不是唯一的字符串属性。然后,很容易用两个Promise.all
来.map
它们——一个等待单个阵列完成,另一个等待所有阵列完成。
对于doSomethingOne
etc函数也应该做同样的事情——为了使代码易于使用,请使用函数数组,而不是使用许多独立的标识符。
此外,不需要显式的Promise构造反模式。
const doSomethings = [
doSomethingOne, // define these functions here
doSomethingTwo,
];
const doSomething = (body) => Promise.all(
body.arrayOfArraysOfIds.map(
(arr, i) => Promise.all(
arr.map(id => doSomethings[i](id))
)
)
)
.then((results) => ({
headers: 'mock headers',
results,
});