Асинхронные итерационные функции, подобные этой, полезны, когда то, что вы делаете с каждым элементом, зависит от базовой асинхронной задачи.
Например, в Node.js операции с файловой системой являются асинхронными (они происходят в отдельном потоке, отличном от JavaScript, и вызывают обратный вызов, когда они завершены). Если вы хотите, скажем, сопоставить список имен файлов с информацией об этих файлах, вы не сможете вернуть результат на карту до тех пор, пока операция файловой системы не перезвонит. Точно так же драйверы баз данных JavaScript, как правило, асинхронны (они выполняют свою работу в другом потоке и по окончании вызывают функцию JavaScript).
Например, допустим, у вас есть список идентификаторов пользователей (например, список пользователей, вовлеченных в вопрос переполнения стека), и вы хотите сопоставить их с подробной информацией о каждом пользователе. С async.js
это может выглядеть так:
async.map([2389, 6344, 27],
function(id, callback){
database.users.find({ id: id }, function(error, user){
if (error) {
callback(error);
} else {
callback(null, {
name: user.name,
reputation: user.reputation,
picture: user.picture
});
}
})
},
function(error, results){
/* results contains:
[
{ name: "Bob", reputation: 10, picture: "http://…" },
{ name: "Fred", reputation: 2910, picture: "http://…" },
{ name: "Steve", reputation: 25000, picture: "http://…" }
]
*/
}
);
Функция итератора вызывается для каждого элемента в массиве и запускает запрос к базе данных, чтобы получить подробную информацию об этом пользователе. Он не будет ждать завершения каждого запроса, прежде чем начинать следующий. Запросы к базе данных могут закончиться очень быстро, или они могут занять некоторое время. Если бы они были синхронными, их можно было запускать только по одному. Хуже того, поток JavaScript не сможет больше ничего делать во время выполнения запросов к базе данных.
Таким образом, не имеет значения, сколько времени занимают запросы к базе данных. Пока они работают, поток JavaScript может быть бездействующим или иметь дело с чем-то другим (например, с другим запросом к серверу).
Когда каждый запрос к базе данных завершается (и они могут даже не завершаться в том же порядке, в котором они были запущены!), Он вызывает функцию обратного вызова, которая помещает информацию о пользователе в объект и передает его его обратный звонок. async.js
отслеживает, какие итерации уже возвращены, и вызывает окончательный обратный вызов только после завершения каждой из них.
Подобные примеры можно найти в документации async.js
.
В браузере меньше асинхронных операций, но вы можете использовать async.js
с запросами к серверу, чтобы загрузить набор ресурсов (например, скрипты или изображения) и убедиться, что все они загружены успешно, или отправлять сообщения между окнами .