使用Express,我使用.map创建一个API调用数组,我希望将其结果组合成一个响应对象。由于每个调用使用不同的查询参数,我想使用查询参数作为响应对象的键。
我使用axios创建GET请求,它返回一个promise,然后我使用axios.all等待所有的promises解析。
问题是在承诺解决后,我不再能够访问用于创建它们的变量。如何将这些变量附加到承诺中供以后参考?
以下是API:
router.get('/api', (req, res) => {
const number = req.query.number;
res.json({ content: "Result for " + number });
});
以下是我尝试合并结果的地方:
router.get('/array', async (req, res) => {
res.locals.payload = {};
const arr = [1, 2, 3, 4, 5];
const promises = arr.map(number => {
return axiosInstance.get('/api', { params: { number: number } })
});
const results = await axios.all(promises);
results.map(r => {
// number should match original, but I no longer have
// access to the original variable
number = 1;
res.locals.payload[number] = r.data;
});
res.json(res.locals.payload);
});
GET on / array的结果:
{
"1": {
"content": "Result for 5"
}
}
创建Promise对象以保存密钥时,我该怎么办?
答案 0 :(得分:0)
如果结果将是一个基于0的索引而不是具有属性“1”,“2”等的对象的数组,我们可以使用Promise.all
(或{{1}如果它提供相同的保证axios.all
它给你的数组将按照你给它的承诺的顺序,无论它们解决的顺序如何)。但我猜你的“数字”实际上是一个更有趣的占位符。 : - )
您可以通过使用promise是管道这一事实来实现这一点,其中各种处理程序在此过程中转换内容。
在这种情况下,您可以将Promise.all
调用的结果转换为具有数字和结果的对象:
get
现在,const promises = arr.map(number => {
return axiosInstance.get('/api', { params: { number } })
.then(result => ({result, number}));
});
回调中的results
会收到一系列具有all.then
和result
属性的对象。如果您愿意,可以使用解构参数在number
回调中接收它们:
results.map
直播示例:
// vvvvvvvvvvvvvvvv---------------- destructuring parameters
results.map(({result, number}) => {
res.locals.payload[number] = result.data;
// ^^^^^^----^^^^^^-------- using them
});
注意我上面使用了ES2015 +属性简写,因为你正在使用箭头功能等。对象初始值设定项// Fake axiosInstance
const axiosInstance = {
get(url, options) {
return new Promise(resolve => {
setTimeout(() => {
resolve({data: `Data for #${options.params.number}`});
}, 300 + Math.floor(Math.random() * 500));
});
}
};
// Fake axios.all:
const axios = {
all: Promise.all.bind(Promise)
};
// Fake router.get callback:
async function routerGet() {
const payload = {}; // stand-in for res.locals.payload
const arr = [1, 2, 3, 4, 5];
const promises = arr.map(
number => axiosInstance.get('/api', { params: { number } })
.then(result => ({result, number}))
);
const results = await axios.all(promises);
results.map(({result, number}) => {
/*res.locals.*/payload[number] = result.data;
});
console.log(/*res.locals.*/payload);
}
// Test it
routerGet().catch(e => { console.error(e); });
与{ number }
完全相同。
附注2:如果您愿意,可以使用简明的箭头函数进行{ number: number }
回调:
map