Redis use sync/await keywords on
Asked Answered
A

4

10

I am new in the JS world, I am creating a query cache and I decide to use redis to cache the information, but I want to know if there is a way to use async/await keywords on the get function of redis.

const redis = require('redis');
const redisUrl = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisUrl);
client.set('colors',JSON.stringify({red: 'rojo'}))
client.get('colors', (err, value) => {
    this.values = JSON.parse(value)
})

I want to know if I can use the await keyword instead of a callback function in the get function.

Assignor answered 2/1, 2020 at 0:28 Comment(0)
S
12

You can use util node package to promisify the get function of the client redis.

const util = require('util');
client.get = util.promisify(client.get);
const redis = require('redis');
const redisUrl = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisUrl);
client.set('colors',JSON.stringify({red: 'rojo'}))
const value = await client.get('colors')

With the util package i modified the get function to return a promise.

Shrivel answered 2/1, 2020 at 0:32 Comment(2)
+1 because the concept is 100% correct. But isn't that first client.get supposed to be below const client?Obsolesce
const redisGet = util.promisify(db_redis.SCAN).bind(db_redis);Breezy
D
7

This is from redis package npm official documentation

Promises - You can also use node_redis with promises by promisifying node_redis with bluebird as in:

var redis = require('redis');
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);

It'll add a Async to all node_redis functions (e.g. return client.getAsync().then())

// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return client.getAsync('foo').then(function(res) {
    console.log(res); // => 'bar'
});
 
// Using multi with promises looks like:
 
return client.multi().get('foo').execAsync().then(function(res) {
    console.log(res); // => 'bar'
});

This example uses bluebird promisify read more here

So after you promsified a get to 'getAsync' you can use it in async await so in your case

const value = await client.getAsync('colors');
Drowse answered 2/1, 2020 at 0:50 Comment(0)
H
4

For TypeScript users both util.promisify and bluebird.promisifyAll aren't ideal due to lack of type support.

The most elegant in TypeScript seems to be handy-redis, which comes with promise support and first-class TypeScript bindings. The types are generated directly from the official Redis documentation, i.e., should be very accurate.

Hollinger answered 3/5, 2021 at 10:25 Comment(0)
B
0

redis with socket io and promisify

import http from 'http';
import redis, { RedisClient } from 'redis';
import { Socket } from 'socket.io';
import { promisify } from 'util';

class SocketWrapper {
  protected _socket?: any;
  protected _client?: RedisClient;

  private _redisExistAsync: any;
  private _redisGetSetMembersAsync: any;

  protected _io?: any;

  get socket() {
    if (!this._socket) {
      throw new Error('Cannot access socket before connecting');
    }
    return this._socket;
  }

  get io() {
    if (!this._io) {
      throw new Error('Cannot access socket before connecting');
    }
    return this._io;
  }

  async exist(id: string) {
    if (!this._client) {
      throw new Error('Cannot access redis before connecting');
    }
    return this._redisExistAsync(id);
  }

  async getSetMembers(id: string) {
    if (!this._client) {
      throw new Error('Cannot access redis before connecting');
    }
    console.log();
    return this._redisGetSetMembersAsync(id);
  }

  async connect(server: http.Server) {
    const io = require('socket.io')(server, {
      path: '/api/sockets/io',
      cors: {
        methods: ['GET', 'POST'],
        credentials: true,
      },
    });
    const client = redis.createClient({
      host: process.env.REDIS_HOST,
      port: 6379,
    });
    client.flushall(); // removing all sets

    this._client = client;
    this._redisExistAsync = promisify(client.exists).bind(client);
    this._redisGetSetMembersAsync = promisify(client.smembers).bind(client);

    io.on('connection', async (socket: Socket) => {
      this._socket = socket;
      const id: string = socket.handshake.query.id + '';
      client.sadd(id, socket.id);
      const status = await this.exist(id);
      const members = await this.getSetMembers(id);
      socket.on('disconnect', async function () {});
    });

    this._io = io;
  }
}

export const socketWrapper = new SocketWrapper();
Bacterin answered 10/8, 2023 at 14:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.