d3-queue
Очередь queue оценивает ноль или более отложенных асинхронных задач с настраиваемой конкурентностью: вы контролируете, сколько задач выполняется одновременно. Когда все задачи завершатся или произойдёт ошибка, очередь передаёт результаты вашему обращению await. Эта библиотека похожа на Async.js’s parallel (когда concurrency бесконечно), series (когда concurrency равно 1) и queue, но имеет гораздо меньший размер: на момент выпуска 2, d3-queue занимает около 700 байт в сжатом виде по сравнению с 4300 для Async.
Каждая задача определяется как функция, которая принимает обратный вызов в качестве последнего аргумента. Например, вот задача, которая говорит hello после короткой задержки:
function delayedHello(callback) {
setTimeout(function() {
console.log("Hello!");
callback(null);
}, 250);
} Когда задача завершается, она должна вызвать предоставленный обратный вызов. Первый аргумент обратного вызова должен быть null, если задача выполнена успешно, или ошибка, если задача завершилась неудачно. Дополнительный второй аргумент обратного вызова — возвращаемое значение задачи. (Чтобы вернуть несколько значений из одного обратного вызова, оберните результаты в объект или массив.)
Чтобы запустить несколько задач одновременно, создайте очередь, отложите свои задачи, а затем зарегистрируйте обратный вызов await, который будет вызван, когда все задачи завершатся (или произойдёт ошибка):
var q = d3.queue();
q.defer(delayedHello);
q.defer(delayedHello);
q.await(function(error) {
if (error) throw error;
console.log("Goodbye!");
}); Конечно, вы также можете использовать for цикл для откладывания многих задач:
var q = d3.queue();
for (var i = 0; i < 1000; ++i) {
q.defer(delayedHello);
}
q.awaitAll(function(error) {
if (error) throw error;
console.log("Goodbye!");
}); Задачи могут принимать необязательные аргументы. Например, вот как настроить задержку перед hello и указать имя:
function delayedHello(name, delay, callback) {
setTimeout(function() {
console.log("Hello, " + name + "!");
callback(null);
}, delay);
} Любые дополнительные аргументы, предоставленные queue.defer, автоматически передаются функции задачи перед аргументом обратного вызова. Вы также можете использовать цепочку методов для лаконичности, избегая необходимости в локальной переменной:
d3.queue()
.defer(delayedHello, "Alice", 250)
.defer(delayedHello, "Bob", 500)
.defer(delayedHello, "Carol", 750)
.await(function(error) {
if (error) throw error;
console.log("Goodbye!");
}); Шаблон асинхронного обратного вызова очень распространён в Node.js, поэтому Queue работает непосредственно со многими API Node.js. Например, для одновременной получения статуса двух файлов:
d3.queue()
.defer(fs.stat, __dirname + "/../Makefile")
.defer(fs.stat, __dirname + "/../package.json")
.await(function(error, file1, file2) {
if (error) throw error;
console.log(file1, file2);
}); Вы также можете создавать отменяемые задачи: эти задачи возвращают объект с методом abort, который завершает задачу. Таким образом, если задача вызывает setTimeout при запуске, она может вызвать clearTimeout при отмене. Например:
function delayedHello(name, delay, callback) {
var id = setTimeout(function() {
console.log("Hello, " + name + "!");
callback(null);
}, delay);
return {
abort: function() {
clearTimeout(id);
}
};
} Когда вы вызываете queue.abort, все активные задачи будут немедленно отменены; кроме того, все ожидающие (ещё не запущенные) задачи не будут запущены. Обратите внимание, что вы также можете использовать queue.abort без отменяемых задач, в этом случае ожидающие задачи будут отменены, хотя активные задачи продолжат выполняться. Удобно, что библиотека d3-request реализует отмену над XMLHttpRequest. Например:
var q = d3.queue()
.defer(d3.request, "http://www.google.com:81")
.defer(d3.request, "http://www.google.com:81")
.defer(d3.request, "http://www.google.com:81")
.awaitAll(function(error, results) {
if (error) throw error;
console.log(results);
}); Чтобы отменить эти запросы, вызовите q.abort().
Установка
Если вы используете NPM, npm install d3-queue. Если вы используете Bower, bower install d3-queue. В противном случае загрузите последнюю версию. Вы также можете загрузить напрямую с d3js.org, как самостоятельную библиотеку или как часть D3 4.0. Поддерживаются AMD, CommonJS и обычные среды. В обычных средах экспортируется глобальная переменная d3:
<script src="https://d3js.org/d3-queue.v3.min.js"></script> <script> var q = d3.queue(); </script>
Попробуйте d3-queue в вашем браузере.
Справочник по API
d3.queue([concurrency]) Источник
Создаёт новую очередь с указанной конкурентностью. Если concurrency не указан, очередь имеет бесконечную конкурентность. В противном случае concurrency — положительное целое число. Например, если concurrency равно 1, все задачи будут выполняться последовательно. Если concurrency равно 3, разрешается одновременное выполнение не более трёх задач; это полезно, например, при загрузке ресурсов в веб-браузере.
queue.defer(task[, arguments…]) Источник
Добавляет указанный асинхронный обратный вызов task в очередь с любыми необязательными arguments. task — функция, которая будет вызвана, когда задача должна начаться. Она получает указанные необязательные arguments и дополнительный callback в качестве последнего аргумента; обратный вызов должен быть вызван задачей при завершении. Задача должна вызвать обратный вызов с двумя аргументами: ошибкой, если она возникла, и результатом задачи. Чтобы вернуть несколько результатов из одного обратного вызова, оберните результаты в объект или массив.
Например, вот задача, которая вычисляет ответ на конечный вопрос о жизни, вселенной и всем остальном после короткой задержки:
function simpleTask(callback) {
setTimeout(function() {
callback(null, {answer: 42});
}, 250);
} Если задача вызывает обратный вызов с ошибкой, любые задачи, которые были запланированы, но ещё не запущены, не будут выполнены. Для последовательной очереди (с concurrency 1) это означает, что задача будет выполнена только если все предыдущие задачи завершатся успешно. Для очереди с большей конкурентностью сообщается только первая произошедшая ошибка обратного вызова await, и задачи, которые были запущены до возникновения ошибки, будут продолжать выполняться; однако обратите внимание, что их результаты не будут переданы обратно в обратный вызов await.
Задачи могут быть отложены только до вызова queue.await или queue.awaitAll. Если задача отложена после этого, будет выброшена ошибка. Если task не является функцией, будет выброшена ошибка.
queue.abort() Источник
Прерывает любые активные задачи, вызывая функцию task.abort каждой активной задачи, если она есть. Также предотвращает запуск новых задач и немедленно вызывает обратный вызов queue.await или queue.awaitAll с ошибкой, указывающей, что очередь была прервана. См. введение для примера реализации отменяемой задачи. Обратите внимание, что если ваши задачи не отменяемые, любые выполняющиеся задачи будут продолжать выполняться даже после того, как обратный вызов await был вызван с ошибкой прерывания. Обратный вызов await вызывается ровно один раз при прерывании, и поэтому не вызывается, когда любые выполняющиеся задачи впоследствии завершаются успешно или с ошибкой.
queue.await(callback) Источник
Устанавливает callback, который будет вызван, когда все отложенные задачи завершатся. Первый аргумент callback — первая возникшая ошибка или null, если ошибок не было. Если произошла ошибка, дополнительных аргументов для обратного вызова нет. В противном случае callback получает каждый результат в качестве дополнительного аргумента. Например:
d3.queue()
.defer(fs.stat, __dirname + "/../Makefile")
.defer(fs.stat, __dirname + "/../package.json")
.await(function(error, file1, file2) { console.log(file1, file2); }); Если все отложенные задачи уже завершены, обратный вызов будет вызван немедленно. Этот метод может быть вызван только один раз после того, как какие-либо задачи были отложены. Если этот метод вызывается несколько раз или после queue.awaitAll, будет выброшена ошибка. Если callback не является функцией, будет выброшена ошибка.
queue.awaitAll(callback) Источник
Устанавливает callback, который будет вызван, когда все отложенные задачи завершатся. Первый аргумент callback — первая возникшая ошибка или null, если ошибок не было. Если произошла ошибка, дополнительных аргументов для обратного вызова нет. В противном случае callback также получает массив результатов в качестве второго аргумента. Например:
d3.queue()
.defer(fs.stat, __dirname + "/../Makefile")
.defer(fs.stat, __dirname + "/../package.json")
.awaitAll(function(error, files) { console.log(files); }); Если все отложенные задачи уже завершены, обратный вызов будет вызван немедленно. Этот метод может быть вызван только один раз после того, как какие-либо задачи были отложены. Если этот метод вызывается несколько раз или после queue.await, будет выброшена ошибка. Если callback не является функцией, будет выброшена ошибка.
© 2010–2017 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-queue