Вопрос об обработке синхронных функций, завернутых в обещание - PullRequest
0 голосов
/ 26 мая 2019

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

Например, если две синхронные функции вызываются по очереди (два последовательных оператора), вторая не начинается до тех пор, пока не вернется первая. Если каждая синхронная функция вместо этого заключена в обещание и затем вызывается одна за другой (не одна в операторе then другого, а два последовательных оператора), будут ли синхронные функции обрабатываться одновременно сейчас, а не по порядку?

У меня есть веская причина спрашивать, кроме интереса к гипотетическому сценарию. Я работаю над расширением, которое открывает вкладки на одной локальной HTML-странице. Когда страница открывается, внедренный сценарий открывает базу данных indexedDB и запускает набор обещаний, которые извлекают данные для каждой вкладки и заполняют различные разделы каждой вкладки соответствующими данными. Размещение их в Promise.all создает впечатление, что вся эта работа выполняется одновременно и заполнение вкладок по мере извлечения данных, в отличие от последовательного заполнения каждой вкладки.

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

Транзакции могут быть разделены так, что для каждой секции вкладок будет одна транзакция, и каждая из функций синхронного отображения начнется, как только будут получены их конкретные данные; но я бы хотел сохранить одну транзакцию для каждой вкладки.

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

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

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

Я прошу прощения за длину этого вопроса, и если он будет сочтен неуместным, поскольку нет кода для проверки, у меня, безусловно, не возникнет проблем при его удалении. Но, если вы можете объяснить, где я не прав в моем понимании, я был бы признателен. Спасибо.

1 Ответ

1 голос
/ 26 мая 2019

Javascript является однопоточным, поэтому в самой среде javascript нет параллелизма.Ваши синхронные функции заполнения разделов будут выполняться по принципу «первым пришел - первым обслужен».

Когда вы вызываете асинхронную операцию, такую ​​как обещание сетевого запроса (или даже вызов setTimeout), это выполнение отправляетсядля обработки вне среды javascript, в ядре ядра, где он может работать без блокировки выполнения js и, возможно, работать в отдельном потоке.

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

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

Где-то есть отличная статья, в которой объясняется, как все это работает намного лучше (и более авторитетно), чем я.Я постараюсь найти его и дополнить свой ответ ссылкой.

Обновление: Этот пост объясняет это довольно хорошо.

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