Перебирайте таблицы Redis и получайте одинаковые ключи в Nodejs и Expressjs - PullRequest
0 голосов
/ 03 июля 2019

Я сохраняю разные данные в разных базах данных на Redis с одним и тем же ключом.Например, в любое время, когда этот скрипт запускается, у меня есть ключи test_1 и test_2 в базах данных 0...100 в Redis.Я пытаюсь сделать для каждой базы данных ключи с одинаковым именем и сохранить данные в файл.Вот фрагмент того, что я пробовал.

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 Ответ

1 голос
/ 03 июля 2019

Вы не можете делать подобные асинхронные вызовы в цикле for. В данный момент вы заставляете узел запускать 100 операторов select, он запускает их, и все они возвращаются в разное время, затем каждый из них запускает свой собственный mget, и в конце концов вы можете попытаться добавить его в файл. Это совсем не то, что вы хотите, даже если это сработает, вы не получите разумный заказ на ваш файл.

Есть несколько способов сделать это, я бы сказал, что самый простой из них, вероятно, с чем-то вроде библиотеки обещаний, так как вы хотите запустить несколько асинхронных запросов, объединить результаты и затем записать файл.

В этом случае я бы сделал что-то вроде следующего. Короткий отказ от ответственности, я не запускаю код, но я считаю, что это должно примерно работать с парой твиков.

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 для итеративных асинхронных процессов немного проще, чем с помощью обратных вызовов, поскольку он предоставляет несколько полезных вспомогательных функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...