我认为简单的例子。我想使用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
完成查找之前将响应发送回去,但我希望该查找完成然后返回响应。
答案 0 :(得分:1)
您正在混合callback
和async/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);
});
并按预期方式获取我的主机名。