为什么redis get in async函数太慢?

s2j5cfk0  于 2021-06-07  发布在  Redis
关注(0)|答案(2)|浏览(710)

我有一个如下代码

console.time('setfoo')
redis.set('foo', 'bar')

...

let result = await redis.get('foo')

console.timeEnd('setfoo')

对此的响应时间 get263ms 但当我离开的时候 await 它可以归结为 0.037ms 原因是什么?

mwg9r5ms

mwg9r5ms1#

我只想说一下:v8(浏览器和nodejs背后的javascript引擎)使用的是一个事件循环(由 libuv )它不一定在单独的线程上执行任务。这个事件循环所做的基本上就是接受作业并在可能的时候执行它们。更多关于事件循环的信息。
话说回来, .get 调用将任务添加到事件循环中,该循环将转换为javascript Promise 对象。如果您不等待,那么任务只是添加到事件循环中。从你的例子来看:

console.time('foo')
let result = redis.get('foo')
console.timeEnd('foo')

您在这里实际测量的是提交事件循环任务需要多少时间?这是无关紧要的。
正在等待 .get 调用不仅会将任务添加到事件循环中,而且还会阻塞,直到任务执行为止:

console.time('foo')
let result = await redis.get('foo')
console.timeEnd('foo')

因此,回答您的问题:这两个时间不应该完全相等,因为一个例子是测量redis处理请求和返回结果所需的时间,而另一个例子是测量作业提交到事件循环所需的时间。

wwodge7n

wwodge7n2#

使用 await 基本上意思是“在你做任何其他事情之前,等待这个指令完成”。不使用它会使脚本执行得很快,但是 result 变量将只包含未解析的承诺。更多关于承诺的信息
在这种情况下,redis不会在本地使用承诺, await 不需要。
我不明白的是你的代码:

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的承诺
编辑:根据redis文档重新编写代码

const { promisify } = require("util");
const getAsync = promisify(client.get).bind(redis);
const setAsync = promisify(client.set).bind(redis);

...

console.time('setFoo')
await setAsync('foo', 'bar')

...

let result = await getAsync('foo', 'bar')
console.timeEnd('setfoo')

相关问题