我正在使用.reduce函数从数组中获取数据,我不确定这是否是最好的方法,但是由于我在另一篇文章中获得的一些帮助,这是目前唯一可行的方法
我不知道如何使用函数中所做的更改来更新数组,返回数组会忽略所做的更改。
数据由路由器提供并每秒更新一次。
var data = [
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: '1.1.1.1',
tx: '0',
rx: '384'},
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: '8.8.8.8',
tx: '384',
rx: '384'},
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: '1.1.1.1',
tx: '384',
rx: '384',},
];
// We resolve the DNS and output the final array
let DNSvariable = result.reduce((arr, currentValue) => {
var setIP = currentValue.dstAddress;
var dns = require('dns');
dns.setServers([
'8.8.8.8',
]);
// Test that IP's are being received correctly.
console.log(setIP);
// Resolve the IP addresses
dns.reverse(setIP, (err, address) => {
currentValue.dstAddress = address;
// If I log the currentValue inside this function everything looks correct, it has updated the values in the full array. I need to push this array, into the returned array.
});
return arr;
}, []);
// Logging the variable produces the array with the original IP
console.log(DNSvariable);
我想要console.log(DNSvariable);返回具有解析名称的数组,此刻它正在返回地址。我只是不知道如何更新数组。
预期结果将是:
var data = [
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: 'one.one.one.one',
tx: '0',
rx: '384'},
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: 'dns.google',
tx: '384',
rx: '384'},
{ macProtocol: 'ip',
ipProtocol: 'udp',
dstAddress: 'one.one.one.one',
tx: '384',
rx: '384',},
];
如果其中任何一个不正确或发布不正确,我深表歉意。
编辑:之所以使用reduce函数,是因为其他所有访问dstAddress的方法都没有以与dns函数一起使用的方式返回数据。显然,这似乎不是正确的方法。
答案 0 :(得分:1)
Reduce看起来并不适合您的用例。我建议使用“地图”方法。 例如,
如果有数组,
var arr1=[{a:1},{a:3},{a:4}]
您需要另一个带有一些修改记录的数组:
var arr2=arr1.map((elem)=>{
const elem2={...elem}
elem2.b=5;
return elem2;
})
console.log('Array1:',arr1)
console.log('Array2:',arr2)
结果:
'Array1:' [ { a: 1 }, { a: 3 }, { a: 4 } ]
'Array2:' [ { a: 1, b: 5 }, { a: 3, b: 5 }, { a: 4, b: 5 } ]
答案 1 :(得分:1)
如果要使用reduce,请代替
return arr
尝试
return [...arr, currentValue]
但是,我认为最好为您提供地图:
let DNSvariable = result.map((currentValue) => {
var setIP = currentValue.dstAddress;
var dns = require('dns');
dns.setServers([
'8.8.8.8',
]);
dns.reverse(setIP, (err, address) => {
currentValue.dstAddress = address;
});
return currentValue;
});
我还建议将这些行移出函数,因为它们只需调用一次即可。
var dns = require('dns');
dns.setServers([
'8.8.8.8',
]);
答案 2 :(得分:0)
首先,使用新的Promises API
const { Resolver } = require('dns').promises;
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);
下一步,解析所有这样的地址:
async function main() {
const promises = data.map(item => resolver.reverse(item.dstAddress));
const hostNames = await Promise.all(promises);
data.forEach((item, i) => {
item.dstAddress = hostNames[i];
});
console.log(data);
}
main();
首先,我们构造一个包含所有可解决承诺的数组。接下来,我们等待所有承诺得到解决。最后,我们用每个对应的结果覆盖.dstAddress
。
编辑:
由于Promise.all
在单个Promise失败的情况下失败,因此以下是将dns.reverse
包装在自定义Promise中的替代版本:
const dns = require('dns');
dns.setServers(['8.8.8.8']);
const reverser = (ipAddress) => new Promise(resolve => {
dns.reverse(ipAddress, (err, hostname) => {
if (err) resolve(ipAddress);
else resolve(hostname);
});
});
如您所见,解析IP失败只会返回IP。这样,即使dns.reverse
本身失败,每个Promise也会解决。
像这样使用:
async function main() {
const promises = data.map(item => reverser(item.dstAddress));
const hostnames = await Promise.all(promises);
data.forEach((item, i) => {
item.dstAddress = hostnames[i];
});
console.log(data);
}
main();