2011-01-17 2 views
11

У меня есть много асинхронных вызовов AJAX, результаты которых будут обработаны. Неважно, какой порядок обработки происходит, но результаты должны обрабатываться по одному. Поэтому я хотел бы просто выполнить мои вызовы AJAX, и все они просто помещают свои результаты в одну очередь. Затем очередь должна обрабатываться в одном потоке. Таким образом, результаты обрабатываются по одному в кратчайшие сроки.Резервная очередь в Javascript или jQuery

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

ответ

25

Asynchronous не означает «несколько потоков». Подумайте о том, как много событий кликов запускаются подряд, прежде чем обрабатывается обработчик первого клика. За один раз можно обрабатывать только одно действие, а остальные будут ждать выполнения.

Языки, управляемые событиями, такие как Javascript, работают на основе очереди. Javascript в фоновом режиме по существу имеет одну гигантскую очередь, в которую вставляются события и асинхронные ответы. Как только какая-то часть обработки будет завершена, будет обработан следующий элемент из очереди.

Эти очереди иногда называют «Runloops». Javascript будет вращаться в бесконечном цикле, извлекать событие из очереди, обрабатывать его и возвращаться в очередь для другой части работы.

Многопоточность может быть достигнута в (более новых) версиях Javascript с использованием Web Workers, но они явно не применяются. Посмотрите их, если вы заинтересованы.

Чтобы ответить на ваш вопрос, просто приложите обратный вызов к асинхронному запросу, и он завершит обработку, даже если другой ответ будет возвращен на полпути. Другой ответ будет «ждать» до тех пор, пока не будет обработано текущее событие.

+6

Я думаю, что каждый из нас с избытком, потому что он использовал слово «потоки». Я считаю, что OP просто означает, что ему нужно, чтобы каждый обратный вызов полностью завершился до следующего запуска. Я предполагаю, что, поскольку jQuery задействован, это происходит из-за того, что происходит какая-то анимация, которая будет использовать таймеры и, следовательно, появляется многопоточность (одновременно могут выполняться два обратных вызова). – beeglebug

+0

@beeglebug - Я не верю, что ты прав. OP явно заявляет: «Неважно, в каком порядке происходит обработка». Это распространенное заблуждение, что асинхронное означает многопоточность, и я считаю, что OP находилось под таким же впечатлением. –

+0

@Josh Smeaton - Возможно, но мы могли бы с самим OP вернуться и пролить некоторый свет. Все сводится к тому, означает ли «обработка» необработанное число хруст или что-то большее, чем пользовательский интерфейс. И с участием jQuery (и, глядя на историю вопроса OP), я думаю, что это UI/анимация. – beeglebug

5

Если ваше единственное беспокойство - браузер (поскольку вы упоминаете jQuery, я предполагаю, что это правда), вы должны знать, что Javascript is single-threaded in browsers.

+2

Ничего себе, я не знал об этом и, кажется, странно ... поэтому я могу сделать 100 запросов AJAX, и кажется, что эти запросы асинхронны и в отдельных потоках, а функции обратного вызова будут вызываться по одному ? –

+0

Я считаю, что это правильно. –

+0

@dorktitude - На самом деле, JavaScript теперь многопоточный, благодаря WebWorkers: https://developer.mozilla.org/En/Using_web_workers – jmort253

0

Простейшим способом было бы реализовать собственную систему очередей для обратных вызовов (используя push/pop для эмуляции стека).

Как только каждый асинхронный запрос возвращается, добавьте данные в конец массива и запустите некоторую команду queue.process(), которая будет обрабатывать первый элемент в массиве.

Наконец, добавьте что-то наподобие if(alreadyRunning) { return; } в начало этой функции, чтобы остановить его выполнение более одного раза, и у вас есть одна очередь с одним потоком.

редактировать: удаление кода, некоторые люди становились вешали на него вместо оригинального вопроса

+0

Единственный раз, когда в вашей очереди будет несколько элементов, если 'this.handler (item)' нажимает на другой рабочий элемент на стек. В этом нет абсолютно никакой необходимости, так как большинство асинхронных вызовов могут принимать обратные вызовы при завершении. –

+0

Я думал, что идея заключается в том, что какой-то внешний код будет отключать вызовы ajax и использовать 'queue.add' в качестве обратного вызова. Таким образом, возвращаемые данные будут добавлены в очередь, и если вторая часть данных была возвращена во время обработки первой, она будет добавлена ​​в очередь, подлежащую обработке после завершения первого. – beeglebug

+0

Невозможно. Другая часть возвращаемых данных НЕ может быть выполнена, пока первая все еще обрабатывается. Он будет ждать, пока только нить станет «свободной» для выполнения работы. 'Queue.add' является избыточным. Просто присоедините обработчик непосредственно к каждому асинхронному запросу. –

0

Вы можете взглянуть на Event messaging between JavaScript objects.

я использовал реализация похожа на запись в блоге с JQuery плагин называется ajaxMonitor.

Способ, которым он работает, как только любой из обратных вызовов из запроса AJAX вызывает его, он обновляет таблицу HTML. Обратные вызовы происходят асинхронно.

Сама природа AJAX означает асинхронность. Поэтому, обрабатывая ваш QUEUE в обратном вызове вашего запроса AJAX, я считаю, что выполнит то, что вы ищете.

Смежные вопросы