d3-queue
Очередь queue оценивает ноль или более отложенных асинхронных задач с настраиваемой параллельностью: вы контролируете, сколько задач выполняется одновременно. Когда все задачи завершатся или произойдёт ошибка, очередь передаёт результаты вашему обратному вызову await. Эта библиотека похожа на Async.js’s параллельную (когда concurrency бесконечна), последовательную (когда concurrency равна 1) и очередь функций, но имеет гораздо меньший размер: по состоянию на релиз 2, d3-queue занимает около 700 байт после сжатия, по сравнению с 4300 для Async.
Каждая задача определяется как функция, которая принимает обратный вызов в качестве последнего аргумента. Например, вот задача, которая приветствует после короткой задержки:
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!");
}); Задачи могут принимать необязательные аргументы. Например, вот как настроить задержку перед приветствием и предоставить имя:
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. Например, чтобы одновременно получить состояние двух файлов:
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 и vanilla. В vanilla, экспортируется глобальная переменная d3:
<script src="https://d3js.org/d3-queue.v3.min.js"></script> <script> var q = d3.queue(); </script>
Попробуйте d3-queue в вашем браузере.
Справочник по API
d3.queue([concurrency]) Источник
Создаёт новую очередь с заданной параллельностью. Если параллельность не указана, очередь имеет бесконечную параллельность. В противном случае параллельность — положительное целое число. Например, если параллельность равна 1, все задачи будут выполняться последовательно. Если параллельность равна 3, то одновременно может выполняться не более трёх задач; это полезно, например, при загрузке ресурсов в веб-браузере.
queue.defer(task[, arguments…]) Источник
Добавляет указанный асинхронный обратный вызов task в очередь с любыми необязательными arguments. task — функция, которая будет вызвана, когда задача должна начаться. Ей передаются указанные необязательные arguments и дополнительный callback в качестве последнего аргумента; обратный вызов должен быть вызван задачей по завершении. Задача должна вызвать обратный вызов с двумя аргументами: ошибкой, если она произошла, и результатом задачи. Чтобы вернуть несколько результатов из одного обратного вызова, оберните результаты в объект или массив.
Например, вот задача, которая вычисляет ответ на последний вопрос жизни, вселенной и всего сущего после короткой задержки:
function simpleTask(callback) {
setTimeout(function() {
callback(null, {answer: 42});
}, 250);
} Если задача возвращает ошибку, любые задачи, которые были запланированы, но ещё не начались, не будут запущены. Для последовательной очереди (с параллельностью 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–2018 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-queue