Node.js 无法理解异步/等待
我认为这是一个简单的例子。我想使用Express根据请求返回用户IP和主机名。但是从IP解析主机名给我带来了一点麻烦Node.js 无法理解异步/等待,node.js,async-await,reverse-dns,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)
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}
,而我希望我也能得到我的主机名。如果Iconsole.log
my hostname,它会打印到控制台,但主机名不会在响应中由express发送回。我做错了什么?我觉得express在dns之前发送了响应。reverse
可以完成查找,但我希望该查找完成,然后返回响应。您将回调
和异步/等待
wait
应与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
}
}
对于节点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}`);
});
}
之后,我用一个async/await
像这样包装了我的logRequest()
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);
});
并按预期获取我的主机名。无需了解async/await即可实现此功能。你需要理解承诺dns.reverse
不会返回承诺,因此无法等待。在我的require('dns')…
之前,删除wait
,并将其包装成new Promise()
是你说的吗?没错。如答案所述,对于最后的节点版本,已经有了它的预期版本。因此,在较新版本的节点中,您不需要…=要求(“dns”)。承诺
,只是const{Resolver}=require('dns')代码>链接的文档。。。是11.0
。。。还有什么比这更新的?文档显示使用.promises
废话,抱歉。我用的是v8.11。所以我需要把我的电话写在一封信里。没错,我不确定你到底需要为8.x做什么。看起来您可以对某些内容使用util.promsify,但使用函数(err,data){return new Promise(…)}
类型的thing@CodyG. 你能再核对一下我在下面贴出的答案,看看这对你是否有意义吗?如果我遗漏了什么?去掉.catch()
你正在吞咽错误,我个人会做if(err){reject(err)}else{resolve(…)}
如果reject被传递给异步错误处理函数,你可能会遇到异步问题。。。resolve也会被调用,这似乎会抛出一些其他类型的奇怪错误,承诺只能被解决或拒绝一次,但我实际上不知道会发生什么。不过这是一个很好的问题资源,我同意。。。基本上,我不喜欢不使用else
或return
,因为您确实可以意外地运行代码。