Что и почему Однажды мне нужно было проанализировать информацию с сайта.
Я взял в руки Node.js и приступил к делу.
Сайт состоял из разделов, каждый раздел состоял из страниц.
Для обработки одного раздела нужно было сделать множество запросов по количеству страниц.
В тот момент мне пришлось столкнуться с ограничениями: сайт начал выдавать ошибку при слишком частых запросах (более нескольких запросов в секунду).
Ну не проблема, подумал я и решил известным способом, сделав своеобразный «асинхронный цикл».
То есть по окончании обработки одной страницы начинался запуск таймера на обработку следующей.
Потом я вспомнил, что мне нужно парсить разные разделы этого сайта и понял, что это становится слишком неудобно.
Поэтому я создал инструмент «Конвейер», который может обрабатывать определенные «элементы данных» (то есть применять функцию-обработчик к заданным объектам) с задержкой по времени между обработкой.
Это также оказалось удобным для «тяжелых» вычислений, которые можно выполнять в цикле в течение длительного времени.
Код конвейера находится по адресу github , ты можешь пройти через это НПМ (так называемый конвейер данных).
Более структурированная помощь также доступна на Github. Вы можете использовать его как хотите, где угодно, без ограничений.
Ниже приведено описание инструмента Конвейер.
Как использовать
Во-первых, вам нужно создать экземпляр объекта «Конвейер», назначив ему обработчик данных:Здесь мы создаем объект, который будет записывать данные в консоль с интервалом 100 мс.var conveyor = new Conveyor(function(element) { console.log(element); }, { period: 100 });
После инициализации следует установить данные: conveyor.add(12);
conveyor.add("Ahoj, Habr!");
conveyor.add([firstElement, secondElement]);
Следует отметить, что в случае массива элементы firstElement и SecondElement будут обрабатываться индивидуально, а не весь массив.
Новые данные можно добавлять в процессе обработки данных, т.е.
конвейер.
add() также можно использовать внутри обработчика, установленного в конструкторе.
Итак, когда мы добавили данные для обработки (кстати, они начинают обрабатываться сразу после добавления), мы можем задать функцию, которая будет вызываться после запуска всех обработчиков событий и ждать заданного интервала: conveyor.whenStop(function() {
console.log('Done.');
});
Таким простым способом мы можем запустить обработку данных с необходимой нам частотой.
Это решило проблему загрузки информации со многих страниц.
Но возникла еще одна проблема.
Сделав функцию типа parseAllPages() (которая загружает информацию со всех страниц одного раздела), я не предусмотрел, что мне захочется вызывать ее для разных разделов одновременно и асинхронно.
Чтобы загрузить информацию из разных категорий, я запустил условную функцию parseAllPages() на другом элементе Conveyor. Но несколько Конвейеров не синхронизированы между собой и поэтому могут выполнять больше запросов в секунду, чем разрешено ограничениями.
Чтобы устранить этот недостаток, в параметры Конвейера был добавлен флаг (логический параметр) useQueue (по умолчанию false).
Установленный этот флаг означает последовательную обработку данных (следующий элемент будет обработан только после обработки предыдущего).
Этот тип обработки позволяет синхронизировать несколько взаимосвязанных объектов Conveyor. Пример: var categoriesConveyor = new Conveyor(function (category, cb) {
parseAllPages(category, function() {
cb();
}
}, {
period: 100,
useQueue: true
});
То есть категории я обрабатывал последовательно, а страницы внутри категории - не последовательно.
Что ж, тогда следуйте описанному алгоритму.
Функция Conveyor.wait(count) также реализована в том случае, если элементы для обработки будут добавлены позже, чем будет вызвана функция WhenStop. То есть функция из WhenStop не будет вызываться до тех пор, пока функция конвейера.
add() не будет вызвана счетчик раз.
Или, если вам больше не нужно добавлять данные, вы можете вызвать функцию Conveyor.unwait(count).
Счетчик ожидаемых элементов также можно установить во время инициализации Конвейера, указав значение параметра ожидаемыеЭлементсКаунтер.
А если вам нужно остановить обработку (игнорируя необработанные элементы), вам следует вызвать функцию Conveyor.forceStop().
Эта штука мне очень помогла.
Надеюсь, что это тоже будет кому-то полезно.
Буду благодарен за ваш отзыв.
Это будет особенно полезно для стиля кода в js. Теги: #JavaScript #conveyor #queue #node.js #io.js #JavaScript #node.js
-
Star О Том, Как Мы Реализовали Доску Задач
19 Oct, 24