Aaron
Aaron

Reputation: 303

Node.js redis promisify with .multi or .batch

Using the npm module 'redis', I've had no problem using utils promisify for single commands.

const { promisify } = require("util");
const redis = require("redis");
const client = redis.createClient();

const hmgetAsync = promisify(client.hmget).bind(client),

Now I want to be able to use the .multi and .batch methods.

Here is an example of one of my helper functions that uses .batch without promisify and non of the promisify versions of commands.

const getData = async (ids) => {
    const batch = client.batch();

    ids.forEach(id => {
        batch.hgetall(id)
    });

    return new Promise((resolve, reject) => {
        batch.exec((err, replies) => {
            if (err) {
                reject(err);
            }

            const data = replies
                // missing keys require filtering
                .filter(it => !!it)
                .map(dataPoint => _toDataPoint(dataPoint));

            resolve(data);
        })
    })
};

Works no problem, but I'm curious if it is possible to use promisify with either .multi or .batch

Many thanks,

Upvotes: 3

Views: 2673

Answers (2)

Gaurav Sharma
Gaurav Sharma

Reputation: 633

Adding more cleaner way of creating Redis batch pipeline and getting response in the format of an array

  async execute(pipeline: any) {
    return await new Promise((resolve, reject) => {
      pipeline.exec((err: any, results: any) => {
        if (err) { reject([]); }
        if (results === null) { resolve([]); }
        else { resolve(results); }
      });
    });
  };
const client = redis.createClient(options);
const batch = client.batch();
batch.get('data1').get('data2').get('data3');
const responses = await execute(client);

Edit:
I had trouble finding number of operations in a redis batch pipeline. Sharing my findings here.

batch.queue.length // this field has number of operations in pipeline

Upvotes: 0

Ihor Sakailiuk
Ihor Sakailiuk

Reputation: 6068

Here is an example of promisified version of multi with an array of commands as an argument:

const { promisify } = require("util");
const redis = require("redis");
const client = redis.createClient();

const multiPromisified = commands => {
        const multi = client.multi(commands);
        return promisify(multi.exec).call(multi);
}

multiPromisified([['get', 'key1'], ['get', 'key2']]);

Upvotes: 4

Related Questions