Что определяет, какие функции Javascript блокируют против неблокирующих?

27

Я работаю с Javascript на основе Интернета (vanilla JS, jQuery, Backbone и т. Д.) Уже несколько лет, а недавно я работал с Node.js. Мне потребовалось некоторое время, чтобы освоить «неблокирующее» программирование, но теперь я привык использовать обратные вызовы для операций ввода-вывода и еще много чего.

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

Я знаю, что операции, которые занимают много времени, такие как операции ввода-вывода в Node и операции AJAX в Интернете, требуют, чтобы они были асинхронными и, следовательно, использовали обратные вызовы - но кто определяет, что можно квалифицировать как «долгое время»? Есть ли какой-то триггер в этих операциях, который удаляет их из обычной "очереди событий"? Если нет, то чем они отличаются от простых операций, таких как присваивание значений переменным или циклическая обработка массивов, от которых кажется, что мы можем зависеть, чтобы завершить синхронно?

Возможно, я даже не думаю об этом правильно - надеясь, что кто-то может привести меня в порядок. Благодарность!

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

Ответы:

13

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

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

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

Асинхронные операции под прикрытием отличаются от синхронных операций тем, что асинхронные операции имеют представление о настройке операции, ее запуске и последующем получении уведомления о ходе, завершении или ошибках в операции. Итерация массива - синхронная операция. У него нет ни одной из этих проблем. Код просто работает синхронно. Вызов ajax-вызова состоит из регистрации обратного вызова для уведомлений о состоянии, затем запуска вызова ajax, затем продолжения выполнения другого javascript и затем через некоторое время обратный вызов вызывается с изменением состояния при вызове ajax (например, завершение).

jfriend00
источник
1
В качестве дополнительного примечания, некоторые функции Javascript являются блокирующими и неблокирующими, в зависимости от их параметров. Например, XMLHttpRequest.openимеет логический asyncпараметр, который определяет, является ли последующий вызов sendасинхронным.
Брайан
Я просто не нашел этот ответ полезным и в целом объяснил.
Мехди Рааш
@MehdiRaash - Ответ в том, что вы понимаете это из документации или из интерфейса. Другого пути нет. Вот что это говорит. Не уверен, что еще ты ожидал. Там нет ответа волшебной пули.
jfriend00
6

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

Вы проверяете документацию. Серьезно - вот для чего. Вы не догадываетесь, что делает функция, основываясь на ее названии или контексте просто так. Если вы не уверены и имеете доступ к его исходному коду, проверьте это.

Это единственный полностью надежный способ.

Теперь для предположения.

  • Если он принимает обратный вызов или возвращает обещание, он, вероятно, асинхронный (я видел исключения для этого правила)
  • Обычно все, что связано с вводом / выводом в node.js и, в более общем случае, в JavaScript, выполняется асинхронно (я тоже видел исключения из этого правила)
Бенджамин Грюнбаум
источник
4

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

1) Текущее выполнение запрашивает внешнюю услугу, такую ​​как запрос ввода-вывода, сетевой запрос или запрос веб-работника.

2) вызов функции ставится на таймер, который будет выполнен позже

Там нет списка блокирующих / неблокирующих функций. Вы должны проверить документацию.

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

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

кодировщик
источник
-1

Я тоже новичок в node.js (и JavaScript в целом), и я не привык к такому асинхронному коду. Я просто хотел отметить, что в разделе Обзор блокирования и неблокирования на nodejs.org говорится, что:

Все методы ввода-вывода в стандартной библиотеке Node.js предоставляют асинхронные версии, которые не являются блокирующими, и принимают функции обратного вызова. Некоторые методы также имеют блокирующие аналоги, имена которых заканчиваются на Sync.

TaborKelly
источник
1
как это решает вопрос? См Как ответить
комар