当前位置: 首页 > 面试题库 >

nodejs,redis。检查密钥是否存在,如果不存在则创建新密钥

乐正浩博
2023-03-14
问题内容

我是NodeJS的新手,也许没有事件系统应该如何工作。找不到错误。请指教。我需要一个简单的任务-
检查标签,如果它不存在,则设置新密钥和有关该标签的信息。问题是-然后我第一次运行该脚本,它始终返回“键不存在”。检查redisdb键-
它会创建很多标签这是我的代码

for (x = 0; x < rows.length; x++) {
    if (rows[x].term_taxonomy_id != 1) {
        var taxonomy = findOne(rterms, rows[x].term_taxonomy_id);
        rc.exists('tag:' + taxonomy.name, function (err, rexists) {
            if (rexists == false) {
                rc.incr('tags:count', function (err, id) {
                    console.log(taxonomy.name+' not exists. result ' + rexists);
                    rc.set('tag:' + taxonomy.name,id);
                    rc.hmset('tag:' + id,
                        'id', id,
                        'title',taxonomy.name,
                        'url', taxonomy.slug
                    );
                });//incr
            }else{
                console.log(taxonomy.name+' exists!'+rexists);
            };
        });//exists
    };//ifrows
});

这是另一个例子

var tags = [
  "apple",
  "tiger",
  "mouse",
  "apple",
  "apple",
  "apple",
  "tiger",
  "mouse",
  "mouse",
];
var count =0;
Object.keys(tags).forEach (function (tag) {
  rc.get("tag:"+tags[tag],function(err,rr){
    console.log("get tag "+tags[tag]+" result code "+rr);
    if (rr == null) {
      rc.set("tag:"+tags[tag],"info",function(err,rr){
        count++;
        console.log('set tag '+tags[tag]+' '+rr+' objects count '+count);
      });
    };
  });
})

输出:

get tag apple result code null
get tag tiger result code null
get tag mouse result code null
get tag apple result code null
get tag apple result code null
get tag apple result code null
get tag tiger result code null
get tag mouse result code null
get tag mouse result code null
set tag apple OK objects count 1
set tag tiger OK objects count 2
set tag mouse OK objects count 3
set tag apple OK objects count 4
set tag apple OK objects count 5
set tag apple OK objects count 6
set tag tiger OK objects count 7
set tag mouse OK objects count 8
set tag mouse OK objects count 9

看起来nodejs仅在该“设置”命令之后执行所有“获取”命令。所以…我了解,这全都归因于异步操作。但是如何使其工作呢?


问题答案:

此代码中至少有两个问题:

  • 第一个链接到Javascript关闭管理。循环的主体不会创建作用域。使用Javascript,变量的范围是在函数级别上,而不是在块级别上。您需要在循环本身中引入一些函数来强制创建适当的闭包。更多信息在这里。

  • 第二个是存在和设置命令之间的竞争条件。如果存在多个正在运行的Redis连接,并在同一键上设置命令,则可能会发生某种冲突。您应该使用setnx来执行检查并在一个原子操作中进行设置,而不是使用存在和设置。

考虑第二个示例,使用forEach解决了关闭问题,但是由于该语言的异步特性,您仍然会在set操作之前生成所有get操作。

如果您真的想对所有get和set操作进行排序(顺便说一句,速度会慢很多),那么您可以使用一些函数式编程来使用递归实现循环。

范例

该程序:

var redis = require('redis')
var rc = redis.createClient(6379, 'localhost');

var tags = [
  "apple",
  "tiger",
  "mouse",
  "apple",
  "apple",
  "apple",
  "tiger",
  "mouse",
  "mouse",
];

var count = 0;

function loop(tags) {
  function rec_loop(tags,i) {
     if ( i >= tags.length )
        return
     rc.get("tag:"+tags[i],function(err,rr) {
        console.log("get tag "+tags[i]+" result code "+rr);
        if ( rr == null ) {
           rc.set("tag:"+tags[i],"info",function(err,rr) {
              count++;
              console.log('set tag '+tags[i]+' '+rr+' objects count '+count);
              rec_loop(tags,++i)
           })
        } else
          rec_loop(tags,++i)
     })
  }
  rec_loop(tags,0)
}

loop(tags)

显示:

get tag apple result code null
set tag apple OK objects count 1
get tag tiger result code null
set tag tiger OK objects count 2
get tag mouse result code null
set tag mouse OK objects count 3
get tag apple result code info
get tag apple result code info
get tag apple result code info
get tag tiger result code info
get tag mouse result code info
get tag mouse result code info

请注意,在此示例中竞赛条件仍然存在。您应该使用setnx来实现这种检查和设置操作。



 类似资料:
  • 所以,我从服务器上获得了一些JSON值,但我不知道是否会有一个特定的字段。 比如: 有时,会有一个额外的字段,如: 我想检查名为“club”的字段是否存在,这样在解析时我就不会得到 组织。json。JSONException:俱乐部没有价值

  • 问题内容: 我陷入一种情况,我需要检查嵌套JSON对象中是否存在密钥。通过嵌套的JSON对象,我在父JSON对象中具有一个JSON对象作为其键之一的值。所以我需要检查此密钥是否存在于整个JSON对象中。我将以下数据作为对象。我知道我可以解析此对象以获得JSON对象。 我已经使用方法来检查主要JSON对象中密钥的存在,并且它可以工作。但是对于检查任何内部JSON对象(例如“ info”),我需要再次

  • 我不熟悉shell脚本,我有一个用于导入cert和使用keytool导入keystore的脚本。此脚本位于Pod中,有时我必须重新启动Pod,有时当此脚本运行时,我会出现此错误 现有条目别名服务器存在,覆盖?[no]:输入新别名(返回以取消此条目的导入): 我知道有命令列出别名 它给出了输出 服务器,2022年6月22日,PrivateKeyEntry,证书指纹(SHA-256):AC:DC:12

  • 问题内容: 仅当密钥存在时,Redis不支持HSET。 http://redis.io/commands#hash 在客户端中实现该功能的最佳方法是什么? 问题答案: 使用事务在客户端实现它很容易。 在WATCH之后删除hkey时,事务将失败。 您还可以使用Redis 2.6中引入的脚本。

  • 我想验证检查密钥是否存在。 有时,会有一个额外的字段,如: 所以我想检查“联系人”键是否存在

  • 问题内容: 是否总是需要在HashMap中检查密钥是否存在? 我有一个说有1000个条目的HashMap,我正在考虑提高效率。如果HashMap的访问非常频繁,则每次访问时检查密钥是否存在将导致大量开销。相反,如果键不存在,因此发生异常,我可以捕获该异常。(当我知道这种情况很少发生时)。这将减少对HashMap的访问。 这可能不是一个好的编程习惯,但是它将帮助我减少访问次数。还是我在这里想念什么?