Условия гонки с обработкой событий JavaScript? - PullRequest
6 голосов
/ 23 декабря 2011

Мы понимаем, что JavaScript является однопоточным, но мы хотим подтвердить наше понимание асинхронной обработки событий в JavaScript. Что еще более важно, мы хотим подтвердить, что мы не подвержены потенциальным условиям гонки.

Концептуально наше мобильное приложение работает следующим образом:

  1. Мы вызываем функцию foo при загрузке мобильной страницы.

  2. В конце foo мы используем setTimeout для повторного вызова foo (с задержкой в ​​одну секунду), если счетчик больше 0. Если счетчик достигает 0, мы загружаем новую страницу. Время ожидания сохраняется в переменной.

  3. Если нажать кнопку, мы вызываем функцию do_tap и очищаем переменную тайм-аута, сохраненную на втором шаге (и делаем другие действия).

do_tap и foo обновляют один и тот же элемент страницы, и мы хотим подтвердить, что они не наступят друг на друга.

Вопросы:

  1. Предположим, что во время выполнения foo происходит касание. Будет ли очередь браузера do_tap запускаться после завершения foo? Другими словами, мы гарантируем, что после запуска foo мы никогда не увидим выполнение чередования foo и do_tap?

  2. Что если сначала произойдет касание? do_tap гарантированно завершится до начала foo, верно?

Ответы [ 4 ]

8 голосов
/ 23 декабря 2011

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

Под обложками у Javascript есть очередь событий. Ваш текущий поток выполнения будет выполняться до конца, а затем, когда он завершится, интерпретатор javascript проверит очередь событий, чтобы увидеть, есть ли еще какие-то действия. Если это так, он запускает это событие и запускает другой поток выполнения. Практически все проходит через эту очередь событий (таймеры, ключевые события, события изменения размера, события мыши и т. Д.).

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

5 голосов
/ 23 декабря 2011

Выполнение события продолжается однопоточным, пока событие не будет обработано. До этого времени никакой другой цикл событий не будет инициирован.

Другими словами, пока обработчик для какого-либо события выполняется, никакой другой обработчик для какого-либо другого события не прервет его.

Таким образом, ответ на вопрос 1 и вопрос 2 - «Да». (Это, конечно, исключение ошибок браузера, но если принять это во внимание, вы не сможете продвинуться далеко вперед. Это не значит, что есть какие-то примитивы синхронизации, к которым можно прибегнуть. во время которого Safari мог запустить событие «DOMready» во время выполнения другого обработчика событий «DOMready». Это, однако, было вполне очевидной ошибкой.)

0 голосов
/ 18 сентября 2014

Я не заметил, чтобы кто-то еще говорил это, но я думаю, что ответ на вопрос №2 заключается в том, что различные реализации браузера могут и действительно различаются в том, какие события в очереди обрабатываются первыми.Нет, нет возможности чередования, но то, будет ли setTimeout (func, 0) или событие мыши обрабатываться первым, не гарантируется спецификацией языка и на практике может иметь значение.Принимая во внимание, что setTimeout (func, 100) равен и гарантированно обрабатывается позже, чем ожидающие события, полученные во время текущего обработанного события.

Просто говорю.

0 голосов
/ 23 декабря 2011

Пока первое, что Do_tap () делает, это clearTimeout, у foo не будет шансов работать во время выполнения Do_tap (). Однако, если в foo () такой запрос к базе данных был инициирован асинхронный процесс, то может возникнуть потенциальное ожидание доступа к базе данных в Do_tap (), поскольку foo () завершает свой запрос, и если foo () имеет функцию обратного вызова, которая теоретически вызывается после выполнения Do_tap ().

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