У меня есть вопрос относительно нативной Array.forEach
реализации JavaScript: он ведет себя асинхронно? Например, если я позвоню:
[many many elements].forEach(function () {lots of work to do})
Это будет неблокирующим?
У меня есть вопрос относительно нативной Array.forEach
реализации JavaScript: он ведет себя асинхронно? Например, если я позвоню:
[many many elements].forEach(function () {lots of work to do})
Это будет неблокирующим?
Ответы:
Нет, это блокировка. Посмотрите на спецификацию алгоритма .
Однако, возможно, более понятная реализация дана в MDN :
Если вам нужно выполнить много кода для каждого элемента, вы должны рассмотреть возможность использования другого подхода:
а затем позвоните с помощью:
Это было бы неблокирующим тогда. Пример взят из высокопроизводительного JavaScript .
Другим вариантом могут быть веб-работники .
источник
forEach
это не блок наawait
заявления например , и вы скорее должны использоватьfor
цикл: stackoverflow.com/questions/37962880/...await
внутриasync
функции. НоforEach
не знает, что такое асинхронные функции. Имейте в виду, что асинхронные функции - это просто функции, возвращающие обещание. Ожидаете ли выforEach
справиться с обещанием, возвращенным после обратного вызова?forEach
полностью игнорирует возвращаемое значение из обратного вызова. Он сможет обработать асинхронный обратный вызов только в том случае, если это будет сам асинхронный вызов.Если вам нужна асинхронная версия
Array.forEach
и аналогичные, они доступны в модуле «async» Node.js: http://github.com/caolan/async ... в качестве бонуса этот модуль также работает в браузере ,источник
eachSeries
вместо этого.Существует общая схема выполнения действительно тяжелых вычислений в Node, которая может быть применима к вам ...
Node является однопоточным (в качестве преднамеренного выбора дизайна см. Что такое Node.js? ); это означает, что он может использовать только одно ядро. Современные боксы имеют 8, 16 или даже больше ядер, так что это может оставить 90 +% простоя машины. Обычный шаблон для службы REST - запуск одного процесса узла на ядро и размещение его за локальным балансировщиком нагрузки, таким как http://nginx.org/ .
Форкинг ребенка - для того, что вы пытаетесь сделать, есть еще одна распространенная модель, которая заключается в том, что вы выполняете тяжелую работу над дочерним процессом. Положительным моментом является то, что дочерний процесс может выполнять тяжелые вычисления в фоновом режиме, в то время как ваш родительский процесс реагирует на другие события. Загвоздка в том, что вы не можете / не должны делить память с этим дочерним процессом (не без МНОГО потрясений и некоторого нативного кода); Вы должны передавать сообщения. Это будет прекрасно работать, если размер ваших входных и выходных данных будет небольшим по сравнению с вычислением, которое необходимо выполнить. Вы даже можете запустить дочерний процесс node.js и использовать тот же код, который вы использовали ранее.
Например:
источник
Array.forEach
Предназначен для ожидающих вычислений, и ничего не получится сделать асинхронными вычисления в цикле событий (веб-работники добавляют многопроцессорность, если вам нужны многоядерные вычисления). Если вы хотите дождаться завершения нескольких задач, используйте счетчик, который можно обернуть в класс семафора.источник
Изменить 2018-10-11: Похоже, есть большая вероятность, что описанный ниже стандарт может не пройти, рассмотрите конвейеризацию как альтернативу (не ведет себя точно так же, но методы могут быть реализованы в подобной усадьбе).
Именно поэтому я в восторге от es7, в будущем вы сможете сделать что-то вроде приведенного ниже кода (некоторые спецификации не завершены, поэтому используйте с осторожностью, я постараюсь держать это в курсе). Но в основном используя оператор new :: bind, вы сможете запустить метод для объекта, как если бы прототип объекта содержал метод. например, [Object] :: [Method], где обычно вы вызываете [Object]. [ObjectsMethod]
Обратите внимание, чтобы сделать это сегодня (24 июля-16) и заставить его работать во всех браузерах, вам понадобится перенести ваш код для следующих функций: импорт / экспорт , функции стрелок , обещания , асинхронное / ожидание и, что наиболее важно, связывание функций . Приведенный ниже код может быть модифицирован для использования только функции связывания, если это необходимо, и все эти функциональные возможности сегодня доступны благодаря использованию babel .
YourCode.js (где « много работы » нужно просто вернуть обещание, разрешив его после выполнения асинхронной работы.)
ArrayExtensions.js
источник
Это короткая асинхронная функция для использования без сторонних библиотек
источник
На npm есть пакет для легкой асинхронности для каждого цикла .
Также еще один вариант для AllAsync
источник
Например, можно закодировать даже такое решение:
С другой стороны, это намного медленнее, чем «для».
В противном случае превосходная библиотека Async может сделать это: https://caolan.github.io/async/docs.html#each
источник
Вот небольшой пример, который вы можете запустить, чтобы проверить это:
Он будет производить что-то вроде этого (если это займет слишком меньше / много времени, увеличьте / уменьшите количество итераций):
источник
Использование Promise.each из Bluebird библиотеки.
Этот метод выполняет итерацию по массиву или обещанию массива, которое содержит обещания (или сочетание обещаний и значений) с заданной функцией итератора с сигнатурой (значение, индекс, длина), где значение является разрешенным значением соответствующее обещание во входном массиве. Итерация происходит поочередно. Если функция итератора возвращает обещание или toableable, то результат обещания ожидается перед продолжением следующей итерации. Если какое-либо обещание во входном массиве отклонено, то возвращенное обещание также отклоняется.
Если все итерации успешно разрешены, Promise.each преобразуется в исходный массив без изменений . Однако, если одна итерация отклоняет или выдает ошибку, Promise.each немедленно прекращает выполнение и не обрабатывает дальнейшие итерации. В этом случае возвращается исходное или ошибочное значение, а не исходный массив.
Этот метод предназначен для побочных эффектов.
источник