Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 为什么Redis进入异步函数太慢?_Node.js_Redis_Async Await - Fatal编程技术网

Node.js 为什么Redis进入异步函数太慢?

Node.js 为什么Redis进入异步函数太慢?,node.js,redis,async-await,Node.js,Redis,Async Await,我有一个如下代码 console.time('setfoo')) redis.set('foo','bar') ... 让result=wait redis.get('foo') console.timeEnd('setfoo') 这个get的响应时间是263ms,但是当我删除wait时,它会下降到0.037ms原因是什么?使用wait基本上意味着“在做任何其他事情之前等待此指令完成”。 不使用它将使脚本快速执行,但result变量将只包含未解析的承诺 在这种情况下,redis不在本地使用承诺

我有一个如下代码

console.time('setfoo'))
redis.set('foo','bar')
...
让result=wait redis.get('foo')
console.timeEnd('setfoo')

这个
get
的响应时间是
263ms
,但是当我删除
wait
时,它会下降到
0.037ms
原因是什么?

使用
wait
基本上意味着“在做任何其他事情之前等待此指令完成”。 不使用它将使脚本快速执行,但
result
变量将只包含未解析的承诺

在这种情况下,redis不在本地使用承诺,因此不需要等待

我不明白的是你的代码:

let result = await redis.get(
  redis.get('foo')
)
您将对redis的调用作为参数传递给另一个对redis的调用。Redis本机使用回调,因此如果要显示从Redis获得的变量,请尝试:

let result = await redis.get('foo', (result) => { console.log(result) })
此外,由于redis.set()是异步的,所以当您尝试恢复数据时,
'foo'
可能尚未设置

编辑:根据redis文档重新编写代码

const{promisify}=require(“util”);
const getAsync=promisify(client.get).bind(redis);
const setAsync=promisify(client.set).bind(redis);
...
console.time('setFoo')
等待setAsync('foo','bar')
...
让结果=等待getAsync('foo','bar')
console.timeEnd('setfoo')

使用
wait
的基本意思是“在执行任何其他操作之前,先等待此指令完成”。 不使用它将使脚本快速执行,但
result
变量将只包含未解析的承诺

在这种情况下,redis不在本地使用承诺,因此不需要等待

我不明白的是你的代码:

let result = await redis.get(
  redis.get('foo')
)
您将对redis的调用作为参数传递给另一个对redis的调用。Redis本机使用回调,因此如果要显示从Redis获得的变量,请尝试:

let result = await redis.get('foo', (result) => { console.log(result) })
此外,由于redis.set()是异步的,所以当您尝试恢复数据时,
'foo'
可能尚未设置

编辑:根据redis文档重新编写代码

const{promisify}=require(“util”);
const getAsync=promisify(client.get).bind(redis);
const setAsync=promisify(client.set).bind(redis);
...
console.time('setFoo')
等待setAsync('foo','bar')
...
让结果=等待getAsync('foo','bar')
console.timeEnd('setfoo')

我想说的是:V8(浏览器和NodeJ背后的JavaScript引擎)使用的是一个事件循环(由
libuv
提供动力),它不一定在单独的线程上执行任务。这个事件循环实际上是接受作业并在可能的时候执行它们。更多关于事件循环的信息

话虽如此,
.get
调用将任务添加到事件循环中,该循环将转换为JavaScript
Promise
对象。如果您不等待,任务将被添加到事件循环中。从你的例子来看:

控制台时间('foo') 让result=redis.get('foo') console.timeEnd('foo') 您在这里实际测量的是提交事件循环任务需要多少时间?这是无关紧要的

等待
.get
调用不仅会将任务添加到事件循环中,还会阻塞直到任务执行:

控制台时间('foo') 让result=wait redis.get('foo') console.timeEnd('foo')
因此,为了回答您的问题:这两个时间应该根本不相等,因为一个例子是测量Redis处理请求和返回结果所需的时间,而另一个例子是测量作业提交到事件循环所需的时间。

在这里扔我的2美分:V8(浏览器和NodeJ背后的JavaScript引擎)使用的是一个事件循环(由
libuv
)不一定在单独的线程上执行任务。该事件循环的作用实质上是接受作业并在可能时执行它们。有关事件循环的更多信息

话虽如此,
.get
调用将一个任务添加到事件循环中,该循环将转换为JavaScript
Promise
对象。如果您不等待,该任务只会添加到事件循环中。从您的示例:

控制台时间('foo') 让result=redis.get('foo') console.timeEnd('foo') 您在这里实际测量的是提交事件循环任务需要多少时间?这是无关紧要的

等待
.get
调用不仅会将任务添加到事件循环中,还会阻塞直到任务执行:

控制台时间('foo') 让result=wait redis.get('foo') console.timeEnd('foo')
因此,为了回答您的问题:这两个时间不应该相等,因为一个例子是测量Redis处理请求和返回结果所需的时间,而另一个例子是测量作业提交到事件循环所需的时间。

这是一个错误,更正了代码。顺便说一句,我使用了ioredisOk、 我当时离这很远,忽略了promisify的一点。ioredis以本机方式处理承诺,所以只需在set()和get()之前放置
wait
应该可以工作。至于响应时间,你的redis服务器距离远吗?这可能就是你的网络响应时间。我不知道网络是什么,因为我的回复速度很快,没有等待。我遗漏了什么吗?如果没有
wait
,你的代码在不等待redis应答的情况下运行。你的redis服务器显然需要263ms的响应时间,这并不重要这似乎是一个代码问题。我不理解这一部分。无论是否等待,Redis的响应时间都应该是相等的否?
timeEnd
应该反映出这一点否?这是一个错误,更正了代码。顺便说一句,我使用ioredisOk,当时我离目标很远,忽略了promisify的部分。ioredis处理承诺本机