遍历Redis表,并在Nodejs和Expressjs中获得相同的键

时间:2019-07-03 15:22:08

标签: javascript node.js express redis

我使用相同的密钥将不同的数据保存在Redis的不同数据库上。例如,在此脚本运行的任何时候,我在Redis中的数据库test_1上都有键test_20...100。我要为每个数据库执行的操作是,获取具有相同名称的键,然后将数据保存到文件中。这是我尝试过的片段。

const redis = require('redis');
const client = redis.createClient();
const fs = require('fs');

for (let i = 1; i <= 100; i++) {
    client.select(i, function(err,res){
        client.mget(['test_1', 'test_2'], function(err,res){
            let results = JSON.parse(res);

            fs.appendFileSync('testfile.json', results);
        });
    });
}

我也尝试将其包装在async函数中,也将await client.mget包装在异步函数中,但是似乎没有任何作用。

1 个答案:

答案 0 :(得分:1)

您不能在for循环中进行这样的异步调用。您目前正在执行的操作是告诉节点运行100条select语句,将它们触发,它们将在不同的时间返回,然后它们将各自启动自己的mget,最终您可能会尝试将它们追加到文件。这根本不是您想要的,即使它可以正常工作,您也无法获得合理的文件顺序。

您可以通过多种方法来执行此操作,我想说最简单的方法可能是使用诸如Promise库之类的东西,因为您要触发一堆异步请求,汇总结果然后编写文件。

在这种情况下,我将执行以下操作。简短的免责声明,我没有运行代码,但是我相信这应该可以通过一些调整大致起作用。

const bluebird = require('bluebird');
const redis = require('redis');
const client = redis.createClient();

// Use bluebird to convert client.select and client.mget into
// promise returning functions rather than callback funcs.
// you could do this with the built in node utils, but we need
// some of bluebirds helper functions later on.
const rSelect = bluebird.promisify(client.select);
const rMget = bluebird.promisify(client.mget);

// Get 0..100 array, there are tons of ways to do this...
const dbIds = Array.from(Array(100).keys());

const operations = dbIds.map(id => {
    return rSelect(i)
        .then(res => {
            return rMget(['test_1', 'test_2']);
        });
});

// You now have an array of promises, one for each database id (0..100).
// We can now execute these promises using a bluebird helper.
// Here I'm using map, if you need them done in a specific order you could
// use mapSeries. You could also use reduce if you'd prefer writing it in
// a reducer style, but that doesn't seem to be what you want.
return bluebird.map(operations)
    .then(allResponses => {
        // "allResponses" now contains the response of every operation.
        // lets write those out to a file.
        var result = JSON.parse(allResponses);
        fs.appendFileSync('testfile.json', result);
    })

在上面的示例中,我使用了Bluebirdjs库,您可以自由使用任何喜欢的库,但这应该可以完成工作。在我的经验中,使用bluebird进行迭代异步过程要比使用回调要容易一些,因为它提供了一些不错的辅助函数。