在异步回调中操作redis的一个异常

WBOY
Freigeben: 2016-06-07 16:38:28
Original
1560 Leute haben es durchsucht

昨天在使用node redis的时候报了这样一个错: TypeError: Object [object Object] has no method 'send_command' at RedisClient.(anonymous function) (D:\index.js:991:25) at null._onTimeout (D:\index.js:17:22) at Timer.listOnTimeout [as ontimeout]

昨天在使用node redis的时候报了这样一个错:

TypeError: Object [object Object] has no method 'send_command' at RedisClient.(anonymous function) (D:\index.js:991:25) at null._onTimeout (D:\index.js:17:22) at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Nach dem Login kopieren

这个bug比较隐蔽,一步一步来看:

起因

我要实现的是批量插入redis的列表(list),相关的api是这样的:client.rpush(key, [value1, value2, ..., callback]),参数必须一个一个列出来,要想批量添加(数组),只能使用apply方法了:

var array = ['list', '1', '2', '3', '4', function() { console.log('success'); } ]; client.rpush.apply(this, array);
Nach dem Login kopieren

数组的第一参数是key,最后一个是回调函数,之间全部是要添加的数据。构造这样一个数组,使用apply就很完美的解决了批量添加的问题。但是还是太年轻啊,执行demo的时候很正常,但是放入正式代码中就有问题了。

解决

正式代码的数据一般是异步得到的,用setTimeout模拟一下:

var redis = require('redis'), client = redis.createClient(6379, '127.0.0.1', { auth_pass: 'home.local.17173.com' }); client.on('error', function(err) { console.log('redis错误:' + err); }); client.on('connect', function() { setTimeout(function() { var array = ['list', '1', '2', '3', '4', function() { console.log('success'); } ]; client.rpush.apply(this, array); }, 1000); });
Nach dem Login kopieren

执行上面的代码会报出文章开头的错误,提示“Object [object Object] has no method ‘send_command’”,联系到apply的this,问题可能出在作用域上,修改倒数第三行代码:

client.rpush.apply(client, array);
Nach dem Login kopieren

执行后就ok了:

所以问题就是出在作用域上,apply这样的比较明显,但是使用async等就不是那么明显了。在stackoverflow上找到一个问题,有bug的代码是这样的:

var async = require('async'); var redis = require('redis'); var keys = ['key1', 'key2', 'key3']; var client = redis.createClient(); var multi = client.multi(); for (var key in keys) { multi.hmset(key, {'some': 'value'}); } multi.exec(function(err, res) { if (err) throw err; console.dir(res); var myCallback = function(err, res) { console.log('in myCallback'); console.dir(res); client.quit(); process.exit(); }; async.concat(keys, client.hgetall, myCallback); });
Nach dem Login kopieren

错误还是和文章开头的一样,解决方法是使用bind函数。修改倒数第二行代码如下:

async.concat(keys, client.hgetall.bind(client), myCallback);
Nach dem Login kopieren

bind函数可以用来设置this参数,具体用法看这里。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!