Методы для того, чтобы модуль узла возвращал «поток» данных?

1

Надеюсь, что я правильно задаю вопрос, но по существу, есть ли способ в NodeJS, чтобы модуль CommonJS возвращал поток данных вместо финализированного фрагмента данных после (длинного) вычисления? Предполагая, что существует несколько способов, каковы эти методы?

Например, скажем, что у меня есть функция findPrimes, написанная как модуль CommonJS:

найти-primes.js

/**
 * @module  findPrimes
 * @param {int} n - Find all primes less than this number
 * @return {array}
 */
module.exports = function(n) {
    if (n < 2) {
        return [];
    } else if (n === 2) {
        return [2];
    }

    var primes = [2];

    for (let i = 3; i < n; i += 2) {
        let is_prime = true;
        let sq = Math.ceil(Math.sqrt(i));

        for (let t = 2; t <= sq; t++) {
            if (i % t === 0) {
                is_prime = false;
                break;
            }
        }

        if (is_prime) {
            primes.push(i);
        }
    }

    return primes;
};

Как вы можете видеть, эта функция возвращает массив всех простых чисел, меньших, чем его вход. Он возвращает массив после вычисления всех этих чисел.

Итак, скажем, я использую этот модуль в сценарии узла

index.js

const primes = require('./find-primes.js');

// Usage: 'node index.js <num>'
let primes_less_than = process.argv[2];

console.log(primes(primes_less_than));

Когда я запускаю вышеуказанный скрипт с аргументом 25, я получаю следующий (ожидаемый) вывод:

$ node index.js 25
[ 2, 3, 5, 7, 11, 13, 17, 19, 23 ]

Однако, скажем, я прошел намного больше, например 10 000 000

$ node index.js 10000000
# Takes a while to run before outputting the numbers...

Хотя это работает, в идеале я хотел бы, чтобы программа начала записывать числа, которые она вычислила, прежде чем она закончится.

Поэтому моя программа все равно займет некоторое время, но она начнет выводить информацию на экран намного быстрее, чем "сначала вычислить ВСЕ, а затем вывести ВСЕ результаты".

Каков наилучший способ достижения этого эффекта? Потоки? Обещания?

Спасибо, я благодарен всем за это.

Теги:
npm

2 ответа

2
Лучший ответ

Вам придется использовать класс Stream из nodejs, и метод должен экспортировать обратный вызов с потоком, как отмечали комментарии:

const stream = require('stream');

function getPrimesStream(n, cb) {
    const primesStream = new stream.Stream();
    cb(null, primesStream);
    if (n >= 2) {
        primesStream.emit('data', 2);
    }

    const primes = [2];

    for (let i = 3; i < n; i += 2) {
        let isPrime = true;
        const sq = Math.ceil(Math.sqrt(i));

        for (let t = 2; t <= sq; t += 1) {
            if (i % t === 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            primesStream.emit('data', i);
            primes.push(i);
        }
    }

    return primes;
}

getPrimesStream(1000, function (err, stream) {
    stream.on('data', function (data) {
        console.log(data);
    });
    stream.on('end', function() {
        console.log('finished');
    });
});
1

Для этого вы можете использовать модуль stream Node.js. Трудно ответить на ваш вопрос в нескольких строках кода, но если вам действительно интересно, как работают потоки, посмотрите на это видео (это я рассказываю о потоках Node.js на собрании Node.js в Мюнхене, Германия).

В качестве альтернативы вы можете использовать функцию генератора с yield, но это также трудно объяснить с нуля в нескольких строках.

В любом случае, потоки и функции генератора - это те термины, которые вы должны искать.

  • 0
    коснулся ... ... ...
  • 1
    > потоки и функции генератора - это термины, которые вы должны искать. Спасибо, я тоже посмотрю это видео, когда у меня будет время. По сути, я пытался найти методы для «отображения частичных данных, рассчитанных с помощью модуля узла», и потоки, похоже, появлялись, но я не смог найти хороших примеров (большинство из них касалось HTTP-запросов). Я хочу, чтобы мне было удобнее писать правильные модули узлов, поэтому к этому я и подхожу.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню