在异步回调中操作redis的一个异常
昨天在使用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)
这个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);
数组的第一参数是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); });
执行上面的代码会报出文章开头的错误,提示“Object [object Object] has no method ‘send_command’”,联系到apply
的this,问题可能出在作用域上,修改倒数第三行代码:
client.rpush.apply(client, array);
执行后就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); });
错误还是和文章开头的一样,解决方法是使用bind
函数。修改倒数第二行代码如下:
async.concat(keys, client.hgetall.bind(client), myCallback);
bind
函数可以用来设置this
参数,具体用法看这里。
原文地址:在异步回调中操作redis的一个异常, 感谢原作者分享。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment nettoyer toutes les données Redis: redis 2.8 et ultérieurement: La commande Flushall supprime toutes les paires de valeurs clés. Redis 2.6 et plus tôt: utilisez la commande del pour supprimer les clés une par une ou utilisez le client redis pour supprimer les méthodes. Alternative: redémarrez le service redis (utilisez avec prudence) ou utilisez le client redis (tel que Flushall () ou FlushDB ()).

Il existe plusieurs mécanismes de communication entre les instances Redis: Pub / Sub: Mode Publish / Sub, permettant une messagerie efficace et à faible latence. Mode de cluster: méthode de déploiement distribué, offrant une haute disponibilité et une tolérance aux défauts. Commande d'installation croisée: permet d'envoyer directement les commandes à une autre instance, adaptée à des fins opérationnelles ou administratives temporaires.

Ce guide fournit deux façons de déterminer la version Redis actuelle: utilisez la commande info pour obtenir le numéro de version. Utilisez l'option --version pour afficher directement le numéro de version. Le numéro de version se compose du numéro de version principale, du numéro de version secondaire et du numéro de révision, qui représentent respectivement les grandes mises à jour de version, les améliorations fonctionnelles et les corrections de bogues mineurs.

Les étapes du redémarrage du cluster redis sont les suivantes: Fermer et effacer les données et les journaux. Démarrez le nœud de graine. Créez un nouveau cluster. Ajouter les nœuds restants. Vérifiez l'état du cluster.

Redis peut être redémarré de deux manières: redémarrage lisse et redémarrage dur. Redémarrer en douceur sans interrompre le service, permettant au client de poursuivre les opérations; Le redémarrage dur termine immédiatement le processus, ce qui fait que le client se déconnecte et perd des données. Il est recommandé d'utiliser un redémarrage en douceur dans la plupart des cas, uniquement si vous devez réparer de graves erreurs ou nettoyer vos données.

Le cluster Redis est un modèle de déploiement distribué qui permet une expansion horizontale des instances Redis, et est implémentée via la communication inter-nœuds, l'espace clé de la division des emplacements de hachage, l'élection du nœud, la réplication maître-esclave et la redirection de commande: communication inter-nœuds: la communication du réseau virtuel est réalisée via le bus de cluster. Slot de hachage: divise l'espace clé en emplacements de hachage pour déterminer le nœud responsable de la clé. Élection du nœud: au moins trois nœuds maîtres sont nécessaires et un seul nœud maître actif est assuré par le mécanisme électoral. Réplication maître-esclave: le nœud maître est responsable de la rédaction de demandes, et le nœud esclave est responsable des demandes de lecture et de la réplication des données. Redirection de commande: le client se connecte au nœud responsable de la clé et le nœud redirige les demandes incorrectes. Dépannage: détection des défauts, marquer la ligne et re

Redis implémente le multi-lancement en combinant intelligemment le mode des réacteurs, le pool de threads et les mécanismes internes multi-threading, en utilisant ainsi efficacement les processeurs multi-core, en améliorant le débit, en optimisant l'utilisation des ressources, en maintenant une faible latence et en améliorant l'évolutivité et en répondant à différents besoins de charge.

Les transactions Redis garantissent les propriétés de l'atomicité, de la cohérence, de l'isolement et de la persistance (acide) et fonctionnent comme suit: Démarrez une transaction: utilisez la commande multi-commandes. Commande d'enregistrement: exécutez n'importe quel nombre de commandes redis. Commit ou enrager les transactions: utilisez la commande exec pour engager la transaction, ou la commande de défausse pour annuler la transaction. Commit: S'il n'y a pas d'erreur, la commande EXEC engage la transaction et toutes les commandes sont appliquées atomiquement à la base de données. Rollback: S'il y a une erreur, la commande de défausse recule la transaction, toutes les commandes sont rejetées et l'état de la base de données reste inchangé.
