在异步回调中操作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的一个异常, 感谢原作者分享。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

1. Starten Sie das Menü [Start], geben Sie [cmd] ein, klicken Sie mit der rechten Maustaste auf [Eingabeaufforderung] und wählen Sie Als [Administrator] ausführen. 2. Geben Sie nacheinander die folgenden Befehle ein (kopieren und fügen Sie sie sorgfältig ein): SCconfigwuauservstart=auto, drücken Sie die Eingabetaste. SCconfigbitsstart=auto, drücken Sie die Eingabetaste. SCconfigcryptsvcstart=auto, drücken Sie die Eingabetaste. SCconfigtrustedinstallerstart=auto, drücken Sie die Eingabetaste. SCconfigwuauservtype=share, drücken Sie die Eingabetaste. netstopwuauserv, drücken Sie die Eingabetaste für netstopcryptS

Heute möchte ich Ihnen einen letzte Woche vom MIT veröffentlichten Artikel vorstellen, in dem GPT-3.5-turbo verwendet wird, um das Problem der Erkennung von Zeitreihenanomalien zu lösen, und zunächst die Wirksamkeit von LLM bei der Erkennung von Zeitreihenanomalien überprüft wird. Im gesamten Prozess gibt es keine Feinabstimmung, und GPT-3.5-Turbo wird direkt zur Anomalieerkennung verwendet. Der Kern dieses Artikels besteht darin, wie man Zeitreihen in Eingaben umwandelt, die von GPT-3.5-Turbo erkannt werden können, und wie man sie entwirft Eingabeaufforderungen oder Pipelines, damit LLM die Anomalieerkennungsaufgabe lösen kann. Lassen Sie mich Ihnen diese Arbeit im Detail vorstellen. Titel des Bildpapiers: Largelingualmodelscanbezero-shotanomalydete

Die Caching-Strategie in GolangAPI kann die Leistung verbessern und die Serverlast reduzieren. Häufig verwendete Strategien sind: LRU, LFU, FIFO und TTL. Zu den Optimierungstechniken gehören die Auswahl geeigneter Cache-Speicher, hierarchisches Caching, Invalidierungsmanagement sowie Überwachung und Optimierung. Im praktischen Fall wird der LRU-Cache verwendet, um die API zum Abrufen von Benutzerinformationen aus der Datenbank zu optimieren. Andernfalls kann der Cache nach dem Abrufen aus der Datenbank aktualisiert werden.

In der PHP-Entwicklung verbessert der Caching-Mechanismus die Leistung, indem er häufig aufgerufene Daten vorübergehend im Speicher oder auf der Festplatte speichert und so die Anzahl der Datenbankzugriffe reduziert. Zu den Cache-Typen gehören hauptsächlich Speicher-, Datei- und Datenbank-Cache. In PHP können Sie integrierte Funktionen oder Bibliotheken von Drittanbietern verwenden, um Caching zu implementieren, wie zum Beispiel Cache_get() und Memcache. Zu den gängigen praktischen Anwendungen gehören das Zwischenspeichern von Datenbankabfrageergebnissen zur Optimierung der Abfrageleistung und das Zwischenspeichern von Seitenausgaben zur Beschleunigung des Renderings. Der Caching-Mechanismus verbessert effektiv die Reaktionsgeschwindigkeit der Website, verbessert das Benutzererlebnis und reduziert die Serverlast.

Ausnahmebehandlung und Unit-Tests sind wichtige Methoden, um die Solidität von C++-Code sicherzustellen. Ausnahmen werden über Try-Catch-Blöcke behandelt. Wenn der Code eine Ausnahme auslöst, springt er zum Catch-Block. Unit-Tests isolieren Codetests, um zu überprüfen, ob die Ausnahmebehandlung unter verschiedenen Umständen wie erwartet funktioniert. Praktischer Fall: Die Funktion sumArray berechnet die Summe der Array-Elemente und löst eine Ausnahme aus, um ein leeres Eingabearray zu verarbeiten. Unit-Tests überprüfen das erwartete Verhalten einer Funktion unter ungewöhnlichen Umständen, z. B. beim Auslösen einer std::invalid_argument-Ausnahme, wenn ein Array leer ist. Fazit: Durch die Nutzung von Ausnahmebehandlung und Komponententests können wir Ausnahmen behandeln, Codeabstürze verhindern und sicherstellen, dass sich der Code unter abnormalen Bedingungen wie erwartet verhält.

Zuerst müssen Sie die Systemsprache auf die Anzeige in vereinfachtem Chinesisch einstellen und neu starten. Wenn Sie die Anzeigesprache zuvor auf vereinfachtes Chinesisch geändert haben, können Sie diesen Schritt natürlich einfach überspringen. Beginnen Sie als Nächstes mit dem Betrieb der Registrierung regedit.exe, navigieren Sie direkt zu HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage in der linken Navigationsleiste oder der oberen Adressleiste und ändern Sie dann den InstallLanguage-Schlüsselwert und den Standardschlüsselwert auf 0804 (wenn Sie ihn in Englisch ändern möchten). us, Sie müssen zunächst die Anzeigesprache des Systems auf en-us einstellen, das System neu starten und dann alles auf 0409 ändern) Sie müssen das System an dieser Stelle neu starten.

Die Behandlung verschachtelter Ausnahmen wird in C++ durch verschachtelte Try-Catch-Blöcke implementiert, sodass neue Ausnahmen innerhalb des Ausnahmehandlers ausgelöst werden können. Die verschachtelten Try-Catch-Schritte lauten wie folgt: 1. Der äußere Try-Catch-Block behandelt alle Ausnahmen, einschließlich der vom inneren Ausnahmehandler ausgelösten. 2. Der innere Try-Catch-Block behandelt bestimmte Arten von Ausnahmen, und wenn eine Ausnahme außerhalb des Gültigkeitsbereichs auftritt, wird die Kontrolle an den externen Ausnahmehandler übergeben.

Die Ausnahmebehandlung in C++ kann durch benutzerdefinierte Ausnahmeklassen verbessert werden, die spezifische Fehlermeldungen und Kontextinformationen bereitstellen und benutzerdefinierte Aktionen basierend auf dem Fehlertyp ausführen. Definieren Sie eine von std::Exception geerbte Ausnahmeklasse, um spezifische Fehlerinformationen bereitzustellen. Verwenden Sie das Schlüsselwort throw, um eine benutzerdefinierte Ausnahme auszulösen. Verwenden Sie „dynamic_cast“ in einem Try-Catch-Block, um die abgefangene Ausnahme in einen benutzerdefinierten Ausnahmetyp zu konvertieren. Im tatsächlichen Fall löst die Funktion open_file eine FileNotFoundException-Ausnahme aus. Das Abfangen und Behandeln der Ausnahme kann eine spezifischere Fehlermeldung liefern.
