Redis服务器可以设置数据但是获取不到
Can set data in Redis server but can't get it
我可以在我的 Redis 服务器中设置一个键的值(当我 flushall
、运行 这段代码,然后在 redis-cli
中获取键时,我得到正确的值),但是当我尝试通过我的 NodeJs 服务器获取键值时,它甚至从未注销 'got data'.
我想这可能是因为这些函数 运行 是异步的,我要求获取尚未存储在缓存中的值,但这并不能解释为什么它不会打印'got data' 曾经。
我的控制台日志-> 'start'->'data saved'->'end'(没有 'got data',永远)
在redis-cli
->flushall
->get test
->(nil)->run app.js
(在另一个终端)->get test->" 1、2、3、4、5"
我完全没有错误,代码 运行s,但没有按照我的意愿去做。
另外,不知道这是否相关,但是当连接到Redis服务器时,只是Redis.createClient()
只创建了一个客户端但没有连接,当我查找时,我得到了一般的想法是较新的版本没有自动连接,您必须手动 redisClient.connect()
.
一开始我遇到了一些问题,但似乎已经解决了这个问题,但只是想我会提到它,如果我以某种方式搞砸了,请纠正我,因为我对 NodeJs 很陌生并且一般编码。
我的代码:
const redisClient = Redis.createClient();
redisClient.connect();
const data = [1, 2, 3, 4, 5];
app.get('/', async(req, res, next) => {
console.log('start')
await redisClient.set('test', data);
console.log('data saved');
await redisClient.get('test', (error, test)=>{
console.log('got data');
console.log(test);
});
console.log('end');
});
谢谢!
我看过你的代码。根据我的调查,您应该删除回调并仅在从 Redis 获取数据时保持等待。
我对这个问题进行了更多调查,发现 client.get()
和 client.set()
函数异步运行。所以才会这样实现。
client.set('foo', 'bar', (err, reply) => {
if (err) throw err;
console.log(reply);
client.get('foo', (err, reply) => {
if (err) throw err;
console.log(reply);
});
});
但每次都不一样use-case 我们应该立即设置并获取值。
要摆脱这个,以下是选项。
Promises
和 async/await
您可以使用本机 Node.js promises
和 util.promisify
:
一次承诺一个 node_redis 函数的子集
示例:
const redis = require('redis');
const { promisify } = require('util');
const runApplication = async () => {
const client = redis.createClient();
const setAsync = promisify(client.set).bind(client);
const getAsync = promisify(client.get).bind(client);
await setAsync('foo', 'bar');
const fooValue = await getAsync('foo');
console.log(fooValue);
};
我在这里使用了await,解决了一个问题。除此之外,您还可以使用 redis.get().then()
来获取数据而不是回调。
我还附加了 link 和 redis repo 提供的示例
https://github.com/redis/node-redis/blob/master/examples/connect-as-acl-user.js
下面是代码,我已经测试过了,现在可以正常工作了。
redis.js
const redis = require("redis");
const redisClient = redis.createClient({
url: "redis://host:6379",
password: "password",
});
redisClient.connect();
// const { promisify } = require("util");
// promisify(redisClient.get).bind(redisClient);
// promisify(redisClient.set).bind(redisClient);
module.exports = redisClient;
index.js
const express = require("express");
const app = express();
const redisClient = require("./redis");
app.get("/set", async (req, res, next) => {
try {
const data = req.query.p;
await redisClient.set("test", data);
res.status(200).json({
message: "data cached",
data: data,
});
} catch (err) {
console.error(err);
res.status(500).json({
message: "Something went wrong",
});
}
});
app.get("/get", async (req, res, next) => {
try {
// const data = await redisClient.get("test");
const data = await reddisClient.get("test").then((data) => {
return data;
});
res.status(200).json({
message: "Cached data retrieved",
data,
});
} catch (err) {
console.error(err);
res.status(500).json({
message: "Something went wrong",
});
}
});
app.listen(process.env.PORT || 3000, () => {
console.log("Node server started");
});
请查看随附的输出屏幕截图。
所以最后的想法是,当我们使用回调并想要同步执行代码时,您应该在回调内部使用回调(但它会创建回调地狱,因此不再建议)或者您应该使用promise/async await/native nodejs 的 promisify 库。
请访问下面link以获得最简单的理解和示例。
https://docs.redis.com/latest/rs/references/client_references/client_nodejs/
希望我的问题能让你头脑清醒。我很高兴接受相关建议来改进答案。
我可以在我的 Redis 服务器中设置一个键的值(当我 flushall
、运行 这段代码,然后在 redis-cli
中获取键时,我得到正确的值),但是当我尝试通过我的 NodeJs 服务器获取键值时,它甚至从未注销 'got data'.
我想这可能是因为这些函数 运行 是异步的,我要求获取尚未存储在缓存中的值,但这并不能解释为什么它不会打印'got data' 曾经。
我的控制台日志-> 'start'->'data saved'->'end'(没有 'got data',永远)
在redis-cli
->flushall
->get test
->(nil)->run app.js
(在另一个终端)->get test->" 1、2、3、4、5"
我完全没有错误,代码 运行s,但没有按照我的意愿去做。
另外,不知道这是否相关,但是当连接到Redis服务器时,只是Redis.createClient()
只创建了一个客户端但没有连接,当我查找时,我得到了一般的想法是较新的版本没有自动连接,您必须手动 redisClient.connect()
.
一开始我遇到了一些问题,但似乎已经解决了这个问题,但只是想我会提到它,如果我以某种方式搞砸了,请纠正我,因为我对 NodeJs 很陌生并且一般编码。
我的代码:
const redisClient = Redis.createClient();
redisClient.connect();
const data = [1, 2, 3, 4, 5];
app.get('/', async(req, res, next) => {
console.log('start')
await redisClient.set('test', data);
console.log('data saved');
await redisClient.get('test', (error, test)=>{
console.log('got data');
console.log(test);
});
console.log('end');
});
谢谢!
我看过你的代码。根据我的调查,您应该删除回调并仅在从 Redis 获取数据时保持等待。
我对这个问题进行了更多调查,发现 client.get()
和 client.set()
函数异步运行。所以才会这样实现。
client.set('foo', 'bar', (err, reply) => {
if (err) throw err;
console.log(reply);
client.get('foo', (err, reply) => {
if (err) throw err;
console.log(reply);
});
});
但每次都不一样use-case 我们应该立即设置并获取值。
要摆脱这个,以下是选项。
Promises
和async/await
您可以使用本机 Node.js
一次承诺一个 node_redis 函数的子集promises
和util.promisify
:示例:
const redis = require('redis'); const { promisify } = require('util'); const runApplication = async () => { const client = redis.createClient(); const setAsync = promisify(client.set).bind(client); const getAsync = promisify(client.get).bind(client); await setAsync('foo', 'bar'); const fooValue = await getAsync('foo'); console.log(fooValue); };
我在这里使用了await,解决了一个问题。除此之外,您还可以使用 redis.get().then()
来获取数据而不是回调。
我还附加了 link 和 redis repo 提供的示例 https://github.com/redis/node-redis/blob/master/examples/connect-as-acl-user.js
下面是代码,我已经测试过了,现在可以正常工作了。
redis.js
const redis = require("redis");
const redisClient = redis.createClient({
url: "redis://host:6379",
password: "password",
});
redisClient.connect();
// const { promisify } = require("util");
// promisify(redisClient.get).bind(redisClient);
// promisify(redisClient.set).bind(redisClient);
module.exports = redisClient;
index.js
const express = require("express");
const app = express();
const redisClient = require("./redis");
app.get("/set", async (req, res, next) => {
try {
const data = req.query.p;
await redisClient.set("test", data);
res.status(200).json({
message: "data cached",
data: data,
});
} catch (err) {
console.error(err);
res.status(500).json({
message: "Something went wrong",
});
}
});
app.get("/get", async (req, res, next) => {
try {
// const data = await redisClient.get("test");
const data = await reddisClient.get("test").then((data) => {
return data;
});
res.status(200).json({
message: "Cached data retrieved",
data,
});
} catch (err) {
console.error(err);
res.status(500).json({
message: "Something went wrong",
});
}
});
app.listen(process.env.PORT || 3000, () => {
console.log("Node server started");
});
请查看随附的输出屏幕截图。
所以最后的想法是,当我们使用回调并想要同步执行代码时,您应该在回调内部使用回调(但它会创建回调地狱,因此不再建议)或者您应该使用promise/async await/native nodejs 的 promisify 库。
请访问下面link以获得最简单的理解和示例。 https://docs.redis.com/latest/rs/references/client_references/client_nodejs/
希望我的问题能让你头脑清醒。我很高兴接受相关建议来改进答案。