gpt4 book ai didi

javascript - node.js/express app - 使用哪种异步方法来替换对 HGET 的嵌套调用?

转载 作者:行者123 更新时间:2023-12-03 05:48:18 28 4
gpt4 key购买 nike

背景

我刚刚学习 Node js,遇到了一种情况,我需要对我的 Redis 数据库进行最多两次连续调用,具体取决于第一个查询的结果。

我现在的代码可以工作..但它非常丑陋。我这样写是因为我不擅长异步“东西”。但现在它正在工作......我想以一种可读的方式进行重构,当然,以一种有效的方式。

这是代码,以及我想要做什么的解释:

代码

  router.get('/:ip', function(req, res, next) {
var ip = req.params.ip;
if ( ! validate_ipV4(ip) ) {
res.status(400).send("Invalid IP");
return;
}

var three_octets = extract_octets(ip, 3);
var two_octets = extract_octets(ip, 2);
if (debug) { winston.log('info', 'emergency router.get() attempting hget using :' + three_octets); }
redis.hget("e:" + three_octets, 'ccid', function (e, d) {
if (e){
winston.log('error', 'hget using key: ' + octets + ' failed with error: ' + e);
res.status(500).send("Database query failed");
return;
}
if (d) {
if (debug) { winston.log('info', 'HGET query using ip: ' + ip + ' returning data: ' + d ) };
res.status(200).send(JSON.stringify(d));
return;
} else {
//retry using only 2 octets
redis.hget("e:" + two_octets, 'ccid', function (e, d) {
if (e){
winston.log('error', 'hget using key: ' + octets + ' failed with error: ' + e);
res.status(500).send("Database query failed");
return;
}
if (d) {
if (debug) { winston.log('info', 'HGET query using ip: ' + ip + ' returning data: ' + d ) };
res.status(200).send(JSON.stringify(d));
return;

}else {
res.status(404).send("Unknown IP");
return;
}
});//end hget
}
});//end hget

});

说明:

接受 IP 地址作为输入。 10.1.1.1

尝试在数据库中查询与前三个八位字节匹配的哈希值。例如:“hget e:10.1.1 ccid”

如果我有匹配项,我可以返回数据库结果并退出。否则,如果查询返回没有结果,那么我需要使用前两个八位字节重试:“hget e:10.1 ccid”

如果没有返回任何内容,那么我可以退出 GET 方法。

异步

我知道有一个异步模块...并且我之前尝试过使用 MAP。但据我了解,你不能强制 MAP 提前退出。例如,如果我做了这样的事情:

  async.map(ipOctets, hash_iterator, function (e, r) { 
})

其中 ipOctets 是一个包含 10.1.1 的数组。和其中的 10.1,如果第一个查询在数据库中找到匹配项,我无法阻止它运行第二个查询。

您能否给我一些关于如何改进此代码的指示,以便我不必重复相同的代码两次?

我还考虑将 redis.hget 调用放入一个单独的函数中...如下所示:

var hash_get = function (hash, key, field) {
if (debug) { winston.log('info', 'hash_get() invoked with : ' + hash + ' ' + key + ' ' + field);}
redis.hget(hash + key, field, function (e, d) {
if (e){
winston.log('hash_get() failed with: ' + e);
return 500;
}
if (d) {
return (d);
}else {
return 404;
}
});
}

但同样,我不确定如何以同步方式执行以下操作:

  • 从 router.get 调用它
  • 检查结果
  • 必要时重复

抱歉提出了菜鸟问题..但任何指点将不胜感激。

编辑 1

自从发帖以来,我发现了这个http://caolan.github.io/async/docs.html#some我目前正在测试这是否适合我。

但是如果您有任何建议,请评论!谢谢。

最佳答案

您可以使用waterfall将函数相互级联的方法。我真的只喜欢在有 3 个或更多嵌套回调时使用它,否则我觉得它不够简化。

查看您的代码并查看可以重用多少后,我想我会使用 async.until不过。

    router.get('/:ip', function(req, res, next) {
var ip = req.params.ip;
if (!validate_ipV4(ip)) {
res.status(400).send("Invalid IP");
return;
}

let success = false;
let octets_num = 3;
async.until(
// Test this for each iteration
function() { return success == true || octets < 2}, // You would adjust the test to set limits
// Do this until above
function(callback) {
let octets = extract_octets(ip, octets_num);
redis.hget("e:" + octets, 'ccid', function(e, d) {
if(e) {
winston.log('error', 'hget using key: ' + octets + ' failed with error: ' + e);
res.status(500).send("Database query failed");
}
else if(id) {
if (debug) { winston.log('info', 'HGET query using ip: ' + ip + ' returning data: ' + d ) };
res.status(200).send(JSON.stringify(d));
success == true;
}
else
{
octects_num--;
}
callback(null);
});
}
// After success or not found within 3 or 2 octets
function(err, result) {
if(success == false) {
res.status(404).send("Unknown IP");
return;
}

}
...
}

这允许您以最小的变化重用相同的代码块。这很粗糙,我没有您的应用程序的其余部分来测试它,但我希望您明白这一点。

关于javascript - node.js/express app - 使用哪种异步方法来替换对 HGET 的嵌套调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40244016/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com