所有Redis命令都是异步的吗?

the*_*gsi 5 javascript asynchronous redis node.js node-redis

我是Redis和Node.JS的新手,并且一直试图将这两者结合使用.但是我对一个接一个地使用哪些功能感到有点困惑.

以下代码似乎同步运行,数据库的大小不断增加:

client.dbsize(function(err, numKeys) {
  console.log("DB Size before hashes added" + numKeys);
  return numKeys;
});

for (var i = 0; i < 100; i++) {
  client.hmset(i, "username", "username", "answer", "answer");
  client.zadd('answer', i, i);
};

client.dbsize(function(err, numKeys) {
  console.log("DB Size after hashes added" + numKeys);
  return numKeys;
});
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试查询排序集'answer'以返回一个数组时,此数组'reply'不能立即用于回调'zrevrangebyscore'之外的其他redis函数.

client.zrevrangebyscore('answer', 100, 0, function(err, reply) {
  console.log (reply);
  return reply;
});
Run Code Online (Sandbox Code Playgroud)

例如,在reply [1]上调用的后续'hgetall'函数返回undefined.我是否应该以异步方式使用所有Redis函数(包括hmset和dbsize)与callbacks/client.multi等,或者如果同步使用有效工作?感谢所有的帮助.

Eli*_*Eli 11

Redis是单线程的,因此Redis上的命令总是按顺序执行.看起来你可能正在使用Redis的异步客户端,这就是混乱的来源.由于您无法保证网络延迟,因此如果您使用的是异步Redis客户端,则稍后调用可能会在之前的调用之前访问Redis服务器并导致您遇到的问题.还有就是为什么在所有存在的Redis异步客户很好的解释在这里.

所有这些都说,在你的情况下,重要的一点是,如果你希望保证命令同步运行,你有几个选择:

  1. 在Redis中使用一个管道只能与服务器一起来回执行所有命令(无论如何,这可能都是个好主意,除非你需要在命令之间做一些事情).
  2. 使用async lib,如此处所述.
  3. 使用同步Redis客户端.我不太了解Node.js知道它有多可行.


Cre*_*ers 0

当谈到同步和异步代码时,您似乎很困惑。我建议您尽可能多地阅读,直到“点击”为止。我将举一个例子来说明发生了什么问题以及原因:

//we're going to fake the redis dbSize function
var dbSize = function(callback){
  //always finishes asynchronously
  console.log("dbsize called");
  setTimeout(callback, 1000);
};

//here we get to your code
dbSize(function(){
  console.log("First callback");
});

console.log("synchronous redis method calls");
//here come the synchronous redis methods, that finish synchronously

dbSize(function(){
  console.log("Second callback");  
});
Run Code Online (Sandbox Code Playgroud)

现在,如果您运行此代码,它将向控制台输出以下内容:

"dbsize called"
"synchronous redis method calls"
"dbsize called"
"First callback"
"Second callback"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在异步方法完成之前调用同步方法。因此,要做的就是确保您随后调用同步方法,这将在第一个回调中,即您必须将这些东西链接在一起。现在这很混乱,因为它会导致你进入回调地狱:

dbSize(function(){

    console.log("First callback");

    console.log("synchronous redis method calls");
    //here come the synchronous redis methods, that finish synchronously

    dbSize(function(){
      console.log("Second callback");  
    });
})
Run Code Online (Sandbox Code Playgroud)

因此,为了避免这种情况,最好使用异步库之类的东西

async.series([
    function(next){
        dbSize(next);
    },
    function(next){
        console.log("synchronous redis method calls");
        //here come the synchronous redis methods, that finish synchronously
        next();            
    },
    function(next){
        dbSize(next);
    },
], function(){
    console.log('All done!');
})
Run Code Online (Sandbox Code Playgroud)

这将输出:

"dbsize called"
"synchronous redis method calls"
"dbsize called"
"All done!"
Run Code Online (Sandbox Code Playgroud)