Javascript 使用在函数内检索和更新的数据更新数组

Javascript 使用在函数内检索和更新的数据更新数组,javascript,node.js,dns,Javascript,Node.js,Dns,我正在使用.reduce函数从数组中获取数据,我不确定这是否是最好的方法,但由于我在另一篇文章中得到了一些帮助,这是目前唯一有效的方法 我不知道如何用函数中所做的更改来更新数组,返回数组会忽略所做的更改 数据由路由器提供,并每秒更新一次 var data = [ { macProtocol: 'ip', ipProtocol: 'udp', dstAddress: '1.1.1.1', tx: '0', rx: '384'}, { macProto

我正在使用.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函数的方式返回数据。这显然不是正确的方法。

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 } ]

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 } ]

如果要使用reduce,则使用

返回arr

试一试

返回[…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', 
]);

如果要使用reduce,则使用

返回arr

试一试

返回[…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', 
]);

首先,使用新的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();
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();
首先,我们构造一个包含所有解析承诺的数组。接下来,我们等待所有承诺得到解决。最后,我们用每个相应的结果覆盖
.dstAddress

编辑:

由于
Promise.all
失败,如果单个承诺失败,这里有一个替代版本,它将在自定义承诺中包装
dns.reverse

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
本身失败,每个承诺都会得到解决

这样使用:

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();
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();

首先,使用新的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();
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();
首先,我们构造一个包含所有解析承诺的数组。接下来,我们等待所有承诺得到解决。最后,我们用每个相应的结果覆盖
.dstAddress

编辑:

由于
Promise.all
失败,如果单个承诺失败,这里有一个替代版本,它将在自定义承诺中包装
dns.reverse

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
本身失败,每个承诺都会得到解决

这样使用:

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();
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();

我不明白代码应该做什么<代码>数组。reduce通常用于将数组转换为单个值;这真的是你想做的吗?这是关于从IP地址获取主机名的吗?
结果从哪里来?
data
是路由器数据的一个例子吗?数据正是路由器提供的。我想获取该数据,并将IP更改为解析的主机名,然后将其用于其他用途。我将用我的预期结果更新帖子。我不明白代码应该做什么<代码>数组。reduce
通常用于将数组转换为单个值;这真的是你想做的吗?这是关于从IP地址获取主机名的吗?
结果从哪里来?
data
是路由器数据的一个例子吗?数据正是路由器提供的。我想获取该数据,并将IP更改为解析的主机名,然后将其用于其他用途。我将用我的预期结果更新帖子。谢谢,这看起来真的很好,但是它产生了与原始代码相同的结果。DNSvariable的输出是IP而不是解析的名称。这看起来非常好,但是它产生的结果与原始代码相同。DNSvariable的输出是IP而不是解析的名称。谢谢,这看起来不错,但是我遇到了这个错误,我应该安装还是包含一些东西<代码>javascript常量{Resolver}=require('dns')。承诺;^TypeError:无法对“undefined”或“null”的属性“Resolver”进行解构我想你可能需要更新你的节点版本?我的是
10.10.0
@Matthew我为没有
dns的旧节点版本添加了一个回退。承诺
@Matthew没问题;)因此,当它工作时,它工作得很好,但是它经常出现这样的错误:我不确定是否需要为此创建一个新的帖子。--------------------------------------------------------------未经处理的PromiserEjectionWarning:错误:getHostByAddr ENOTFOUND 121.162.224.54------------------------------------------------------(节点:18316)未经处理的PromiserEjectionWarning:未经处理的承诺拒绝。此错误源于在没有catch块的情况下抛出异步函数的内部,或者拒绝未使用.catch()处理的承诺。谢谢,这看起来不错,但是我遇到了此错误,我应该安装或包含什么吗<代码>javascript常量{Resolver}=require('dns')。承诺;^TypeError:无法对“undefined”或“null”的属性“Resolver”进行解构我想你需要更新你的节点v