Асинхронное программирование в JavaScript (НЕ AJAX) - PullRequest
8 голосов
/ 21 июля 2010

Возможно ли делать вещи асинхронно в JavaScript (кроме AJAX)? Например, для итерации нескольких массивов одновременно. Как это сделать? Краткий пример был бы хорош. Поиск этого был трудным, из-за загрязнения ajax, что я не ищу.

Заранее спасибо.

Ответы [ 6 ]

9 голосов
/ 21 июля 2010

Использование Web Workers . Но помните, что это очень новая функция, и не все браузеры полностью поддерживаются.

6 голосов
/ 21 июля 2010

Вы можете использовать setTimeout.

setTimeout(function () { iterateArray(array1); reportDone(1); }, 0);
setTimeout(function () { iterateArray(array2); reportDone(2); }, 0);

Я не уверен, насколько это будет параллельным, но это модель асинхронного программирования.

4 голосов
/ 21 июля 2010

Как утверждает Grumdrig, вы можете написать код, подобный этому:

setTimeout(function () { iterateArray(array1); reportDone(1); }, 0);
setTimeout(function () { iterateArray(array2); reportDone(2); }, 0);

Но он все равно не будет работать одновременно. Вот общее представление о том, что происходит после того, как такие тайм-ауты называются:

  • Любой код после setTimeout вызовов будет запущен немедленно, включая возврат к вызывающим функциям.
  • Если в очереди есть другие таймеры, которые имеют задержку или интервал времени или превышают их, они будут выполняться по одному за раз.
  • Пока работает любой таймер, другой может нажать на интервал / время задержки, но он не будет работать до тех пор, пока не закончится последний.
  • Некоторые браузеры отдают приоритет событиям, инициируемым от взаимодействия с пользователем, таким как onclick и onmousemove, и в этом случае функции, связанные с этими событиями, будут выполняться за счет точности таймера.
  • Это будет продолжаться до тех пор, пока не произойдет открытие (ранее не вызывавшиеся таймеры или обработчики событий, запрашивающие выполнение). Только тогда будут выполняться функции в примере кода. Опять по одному, первое вероятно, но не обязательно выполняется первым. Кроме того, я рискну предположить, что некоторые браузеры могут устанавливать минимальное время задержки, что приведет к запуску любых таймеров с задержкой 0 миллисекунд даже позже, чем ожидалось.

Очевидно, что при запуске такого кода нет никакого преимущества в производительности. В любом случае это займет больше времени. Однако в тех случаях, когда одна задача занимает так много времени, она замораживает браузер (и, возможно, отключает «браузер требует слишком много времени» предупреждений браузера), может быть полезно разбить ее на более мелкие, быстрее выполняющиеся фрагменты, которые запускаются последовательно после некоторого времени задержки , таким образом, давая браузеру время дышать.

Web Workers уже упоминались, и если вас не беспокоит совместимость с IE, вы можете использовать их для истинного параллелизма. Однако существуют некоторые серьезные ограничения на их использование, наложенные по соображениям безопасности. Для одного они не могут взаимодействовать с DOM каким-либо образом, означая, что любые изменения на странице все равно должны выполняться синхронно. Также все данные, передаваемые рабочим и от них, сериализуются при передаче, что означает, что настоящие объекты Javascript не могут быть использованы. При этом для интенсивной обработки данных веб-работники, вероятно, являются лучшим решением, чем разбивка функций на несколько задач с задержкой по таймеру.

2 голосов
/ 21 июля 2010

Одна новая разработка в этой области - HTML5 Web Workers.

1 голос
/ 26 сентября 2010

Я должен согласиться с MooGoo, мне также интересно, почему вы пробежите такой большой массив за один раз.

Существует расширение JavaScript, называемое StratifiedJS , оно позволяет вам выполнять несколько действий одновременно, пока они асинхронны. Кроме того, веб-работники являются неудобным «решением», которое просто усложняет задачу, а также они не работают в IE.

В Стратифицированном JS вы могли бы просто написать.

waitfor {
   // do something long lasting here...
}
and {
  // do something else at the same time...
}
// and when you get here, both are done
1 голос
/ 21 июля 2010

JavaScript обычно однопоточный;Вы не можете сделать несколько вещей одновременно.Если ваш JavaScript-код слишком медленный, вам придется разгрузить работу.Новый способ заключается в использовании веб-работников , как отметили другие.Старый способ часто состоит в том, чтобы использовать AJAX и вместо этого выполнять работу на сервере.(Либо с веб-работниками, либо с AJAX, массивы нужно будет сериализовать и десериализовать результат)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...