Проблема понимания Async / Await - PullRequest
0 голосов
/ 01 ноября 2018

Простой пример, я думаю. Я хочу использовать 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 отправляет ответ обратно до того, как dns.reverse сможет завершить поиск, но я хочу, чтобы поиск завершил , а затем вернул ответ.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

С узлом 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);
}

В этот момент я могу сделать запрос на экспресс с

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

И получите мое имя хоста, как и ожидалось.

0 голосов
/ 01 ноября 2018

Вы смешиваете callback и async/await

await следует сочетать с Promise

В вашем случае dns.reverse не является обещанием и ничего не возвращает.

Во-первых, вам нужно использовать днс обещание

Затем вам нужно обновить 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
  }
}
...