[英]How to correctly use Promise.all to combine two datasets and return a single object?
I have an existing object data
.我有一个现有的对象
data
。 I am using NodeJS async
function to retrieve value of fetchResponse
.我正在使用 NodeJS
async
函数来检索fetchResponse
值。 Finally, I am trying to embed the fetchResponse
to the existing data
object using the following for loop
最后,我尝试使用以下
for loop
将fetchResponse
嵌入到现有data
对象中
for (let key in data) {
for (let number in data[key]) {
data[key][number].map( async d=> {
const fetchResponse = await sequelize
.query(await fetchHostDetails(d.Hostname), options);
data[key][number]['Fetchresult'] = fetchResponse;
});
}
}
return data;
I see that data
is still having the original value and not including the key value pair
Fetchresult : fetchResponse
我看到
data
仍然具有原始值并且不包括key value pair
Fetchresult : fetchResponse
I am trying to use Promise.All
as below but it is still giving original data
object value.我正在尝试使用
Promise.All
如下,但它仍然提供原始data
对象值。
for (let key in data) {
for (let number in data[key]) {
data[key][number].map( async d=> {
const fetchResponse = await sequelize
.query(await fetchHostDetails(d.Hostname), options);
await Promise.all({...d, Fetchresult : fetchResponse});
});
}
}
return data;
const data =
{
"error1": {
"7": [
{
"ErrorType": "Error-1A",
"Hostname": "host123.com"
}
],
"8": [
{
"ErrorType": "Error-1B",
"Hostname": "host223.com"
},
{
"ErrorType": "Error-1C",
"Hostname": "host1231.com"
}
]
}
}
I am getting below fetchResponse
for hostName under Error-1A
我在
Error-1A
下低于 hostName 的fetchResponse
const fetchResponse =
[
{
"resType": "unknow data",
"res": "missing data"
},
{
"resType": "login failed",
"res": "login with wrong userid"
}
]
Similarly there will be separate fetchResponse
for hostName under Error-1b
and Error-1C
but response format will be similar to what we have got for Error-1A
.同样,
Error-1b
和Error-1C
下的 hostName 将有单独的fetchResponse
,但响应格式将类似于我们为Error-1A
获得的格式。
For data.error1[8]
we are getting 2 values of fetchResponse
but please note that those are 2 separate values for Error-1B
and Error-1C
.对于
data.error1[8]
我们得到了fetchResponse
2 个值,但请注意,这些是Error-1B
和Error-1C
两个单独的值。 One will be displayed after Error-1B
and other will be displayed after Error-1C
.一个将在
Error-1B
之后显示,另一个将在Error-1C
之后显示。
It doesn't make sense to me to use await
in a loop.在循环中使用
await
对我来说没有意义。 I'd prefer to generate a single, flat list of promises to eventually have one Promise.all
that awaits them all.我更喜欢生成一个单一的、平面的
Promise.all
列表,最终有一个Promise.all
等待它们。
Allow me to use a placeholderAsyncOperation
to stand in for your fetch using the key and number.允许我使用
placeholderAsyncOperation
来代替您使用键和数字进行提取。 For demonstration purposes, I'll just delay a bit and then returns some object based on the parameters.出于演示目的,我将稍微延迟一下,然后根据参数返回一些对象。 I'll use your original input
data
though.不过,我会使用您的原始输入
data
。
const data = { "error1": { "7": [ { "ErrorType": "Error-1A", "Hostnames": "host123.com,hostabc.com,host33a.com..." } ], "8": [ { "ErrorType": "Error-1B", "Hostnames": "host223.com,host2c.com,host43a.com..." }, { "ErrorType": "Error-1C", "Hostnames": "host1231.com,host2abc.com,host313a.com..." } ] }, "error2": { }, "error3": { } } async function placeholderAsyncOperation(key, number, result) { await delay(1000); return {key, number, resultJSON: JSON.stringify(result)}; } const delay = time_ms => new Promise(resolve => setTimeout(resolve, time_ms)); let promises = []; for (let key in data) { for (let number in data[key]) { promises.push(data[key][number].map(val => (placeholderAsyncOperation(key, number, val)))); } } Promise.all(promises.flat()).then(result => console.table(result));
This uses console.table
that Stack Overflow doesn't support so well yet (output embedded into the page will appear empty), so if you run this snippet in your browser you'll likely have to open your browser's built-in console before running the snippet .这使用了 Stack Overflow 尚不支持的
console.table
(嵌入页面的输出将显示为空),因此如果您在浏览器中运行此代码段,您可能必须在运行之前打开浏览器的内置控制台片段。 Like, by pressing F12 or however your browser shows its console.就像,通过按 F12 或您的浏览器显示其控制台。
I would first of all build an array containing all the promises, along with key and index:我首先会构建一个包含所有承诺以及键和索引的数组:
let promises = [];
for (let key in data) {
for (let number in data[key]) {
let p = async() => {
const fetchResponse = await sequelize.query(
await fetchHostDetails(d.Hostname), options
);
return {key, number, fetchResponse};
};
promises.push(p);
}
}
Now, before you inject this "fetch" data into your original data, the promises need to resolve.现在,在您将此“获取”数据注入原始数据之前,需要解析 promise。 So we use an async function:
所以我们使用一个异步函数:
const merge = async (data, promises) => {
// wait for all promises
const resolvedPromises = await Promise.all(promises);
// inject the results into "data"
resolvedPromises.forEach(row => {
if (row) {
const {key, number, fetchResponse} = row;
data[key][number]['Fetchresult'] = fetchResponse;
}
});
return data;
};
When you call this, remember it's async:当你调用它时,记住它是异步的:
merge(data, promises).then(newData => {
console.log(newData);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.