Есть ли у процесса Javascript несколько потоков выполнения? - PullRequest
5 голосов
/ 19 декабря 2010

Фон

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

Мои многие вопросы

Концептуально, я знаю, как это сделать, но мне не ясны ограничения движка Javascript:

  1. Зависит ли порядок исполнения браузера? Одна из вещей, которые я пытался сделать, это поставить в очередь набор записей (A, B, C и т. Д.), А затем сделать целую кучу запросов одновременно. Это было не очень успешно. Я получил большинство звонков назад, но не в каком-то определенном порядке. Мне нужны все мои звонки обратно. :)

  2. Как мне отладить это / отследить это? Я не уверен, как Javascript обрабатывает ответ; это было достаточно просто для одного ответа, но я не уверен, как обрабатывать несколько относительно больших ответов от сервера.

  3. Есть ли один поток выполнения для данной страницы? То есть, если Javascript получает ответ от сервера, но все еще выполняет код, блокирует ли транзакция, пока не завершится текущий исполняемый код?

  4. Будет ли рекомендована задержка между запросами? Это также может вызвать проблемы, поскольку загрузка и отправка запроса (на данный момент) находится на этапе инициализации; если мне придется спать () между запросами, я мог бы просто заставить пользователя ждать загрузки всех данных, не пытаясь выполнить эту постепенную загрузку.

Я посмотрел на SO, но не нашел ничего полезного. Мне интересно, как JS обрабатывает эти асинхронные запросы / ответы.

Что я сделал до сих пор

Просто чтобы дать людям лучшее представление о том, что происходит, вот что я делаю в порядке исполнения. Существует 5 жестко запрограммированных категорий поиска: имена, фамилии, классы, регионы, штаты. У каждой из этих категорий есть диапазоны. Например, категория имен может иметь 26 диапазонов, по одному для каждой буквы алфавита: «Aardvark - Azariah» будет примером диапазона. Каждый диапазон содержит информацию о пользователях для каждого пользователя в этом диапазоне. У меня есть две таблицы: таблица диапазонов и таблица пользователей.

  1. Инициализация таблицы диапазона и объектов источника данных диапазона. Сопоставить объект таблицы диапазона с конкретными событиями.
  2. AJAX вызов, чтобы получить все диапазоны для каждой категории. Мы ждем этого, прежде чем продолжить.
  3. Инициализировать таблицу пользователей аналогично таблице диапазонов.
  4. Создайте очередь загрузки, чтобы получить всех пользователей для каждого диапазона. Очередь загрузки выглядит следующим образом: [lastNames ['S'], регионы ['CA'], регионы ['northwest'], lastNames ['A'] и т. Д.]
  5. Предварительно выберите категорию имен, диапазон имен «А» и нулевого пользователя в этом диапазоне. (Это просто произвольный выбор, который я сделал, чтобы дать пользователю отправную точку)
  6. AJAX-вызов для получения всех пользователей для firstName ['A']. Удалите диапазон firstNames ['A'] из очереди загрузки.
  7. Заполните соответствующие элементы интерфейса
  8. Цикл нашей очереди загрузки, освобождение от диапазонов и построение AJAX-запросов на данные.

Есть также много других деталей ... но это основная суть.

Что происходит, так это то, что моя таблица диапазонов заполняется нормально ... но затем браузер просто блокируется (spod), а затем моя таблица пользователей получает всевозможные сумасшедшие данные, заполняемые в ней. Ясно, что последний является ошибкой пользовательского интерфейса с моей стороны, поэтому я должен исследовать это, но мне не ясно, что это лучший способ сделать это.

На шаге 7 я не уверен, должна ли быть задержка между запросами. В идеале, если пользователь выберет определенный диапазон, скажем, состояния ['AK'], мы сначала обработаем этот запрос, используя этот диапазон из нашей очереди загрузки. Но если я отправлю все запросы на внешний интерфейс, то у нас никогда не будет возможности дать выбранному диапазону соответствующий приоритет.

Ответы [ 4 ]

8 голосов
/ 19 декабря 2010

Javascript полностью однопоточный.

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

Если ваш код все еще работает, когда сервер отвечает, ответ будет обработан только после его завершения.

Вы должны попытаться загрузить все данные в одном запросе.

1 голос
/ 19 декабря 2010

Ajax расшифровывается как «Асинхронный JavaScript и XML».«Асинхронный» означает, что во время запроса нет способа узнать, в каком порядке будут поступать ответы.

JavaScript не имеет (на данный момент) механизма для создания потоков, поэтому у вас есть две возможности:

  1. Запросить следующую часть после получения последней.Это может быть очень медленно и неэффективно, потому что один запрос на зависание заблокирует все остальные.
  2. Создайте список / массив для всех возможных запросов и начните загрузку важных.Если пользователь хочет что-то еще, начните загружать остальные тоже.Храните ответы в правильной позиции в вашем массиве;Это сделает ваш скрипт независимым от порядка, и вы можете проверить, все ли там, просто перебирая массив.
1 голос
/ 19 декабря 2010

Зависит ли порядок исполнения браузера?Одна из вещей, которые я пытался сделать, это поставить в очередь набор записей (A, B, C и т. Д.), А затем сделать целую кучу запросов одновременно.Это было не очень успешно.Я получил большинство звонков назад, но не в каком-то определенном порядке.Мне нужны все мои обратные вызовы.

Порядок выполнения не зависит от браузера.Они управляются событиями, и события зависят от вас.Когда вы говорите «очередь», в миксе нет очереди сообщений;Вы имеете в виду любой механизм, который есть у сервера, чтобы принимать их и назначать потокам.

Время возврата звонков определяется продолжительностью, необходимой для их выполнения.Между вашим браузером и сервером существует недетерминированная сеть, поэтому вы не сможете сказать.

Как мне отладить это / отследить это?Я не уверен, как Javascript обрабатывает ответ;это было достаточно просто для одного ответа, но я не уверен, как обрабатывать несколько относительно больших откликов с сервера.

В Google Chrome есть несколько очень хороших инструментов отладки, подаренных Apple и сделанныхОткрытый исходный код.Проверьте это.Или вы можете попробовать Firefox Firebug.

Есть ли один поток выполнения для данной страницы?То есть, если Javascript получает ответ от сервера, но все еще выполняет код, блокирует ли транзакция, пока не завершится текущий исполняемый код?

JavaScript является однопоточным.

Будет ли рекомендована задержка между запросами?Это также может вызвать проблемы, поскольку загрузка и отправка запроса (на данный момент) находится на этапе инициализации;если мне придется спать () между запросами, то я мог бы просто заставить пользователя ждать загрузки всех данных, не пытаясь выполнить эту постепенную загрузку.

Я бы не стал ставитьзадержка между запросами.Я думаю, что это побеждает цель.

Я бы посоветовал посмотреть на jQuery, чтобы помочь с этим.

0 голосов
/ 19 декабря 2010

JavaScript - это четный язык программирования, поэтому вы увидите много такого шаблона:

someFunction(arguments, callbackFunction () {
  // code fired after a process or event is fired
});

Если вы не получаете ответы на все ваши запросы, что-то не так с вашей реализацией или ресурсом, к которому вы обращаетесь. Вы можете использовать Firebug, чтобы глубже понять, что происходит.

Используете ли вы какие-либо JavaScript-фреймворки, они делают использование запросов XHR (a.k.a. Ajax) довольно простым. Я рекомендую jQuery.

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