无法理解异步/等待

时间:2018-11-01 15:18:20

标签: node.js async-await reverse-dns

我认为简单的例子。我想使用Express根据请求返回用户IP和主机名。但是从IP解析该主机名给我带来了一些麻烦。

router.get('/', (req, res) => {
    logRequest(req, res);
});

async function logRequest(req, res) {
    res.send({
        ip: req.ip,
        hostname: await getRemoteHostName(req.ip)
    });
}

async function getRemoteHostName(ip) {
    await require('dns').reverse(ip, (err, domains) => {
        if (err) { handleError(err); return; }
        return domains.map(s => s.toLowerCase());
    });
}

当我期望自己也应该重新获得主机名时,我得到的只是我的IP {ip: 192.168.10.100}。如果我用console.log的主机名将其打印到控制台,但是主机名不会在响应中通过Express发送回去。我究竟做错了什么?我觉得express是在dns.reverse完成查找之前将响应发送回去,但我希望该查找完成然后返回响应。

2 个答案:

答案 0 :(得分:1)

您正在混合callbackasync/await

await应该与Promise

结合使用

在您的情况下,dns.reverse不是承诺,什么也不会退回。

首先,您需要使用dns promise

然后,您需要更新getRemoteHostName以返回主机名并处理错误

const { Resolver } = require('dns').promises;
const resolver = new Resolver();

async function getRemoteHostName(ip) {
  try {
    const hostnames = await resolver.reverse(ip)
    // your logic here
    return hostnames
  } catch(error) {
    // handle error here
  }
}

答案 1 :(得分:0)

对于节点v8.11.3,我需要证明我的getRemoteHostName()方法的正确性。

function getRemoteHostName(ip) {
  return new Promise((resolve, reject) => {
    require('dns').reverse(ip, (err, domains) => {
      if (err) { reject(err); }
      resolve(domains.map(d => d.toLowerCase()));
    });
  }).catch(error => {
    console.log(`error: ${error}`);
  });
}

此后,我像这样用logRequest()包裹了async/await

async function logRequest(req, res) {
  const client = {
    ip: req.ip,
    hostname: await getRemoteHostName(req.ip)
  };

  res.send(client);
}

这时我可以向Express提出请求

router.get('/', (req, res) => {
    logRequest(req, res);
});

并按预期方式获取我的主机名。