Що визначає, які функції Javascript блокуються проти не блокуючих?


27

Я вже декілька років займаюся веб-JavaScript (vanilla JS, jQuery, Backbone тощо), і останнім часом я займаюся деякою роботою з Node.js. У мене знадобився певний час, щоб розібратися з "неблокуючим" програмуванням, але зараз я звик використовувати зворотні дзвінки для операцій вводу-виводу і чогось іншого.

Я розумію, що Javascript від природи однопотоковий. Я розумію концепцію Вузла "черга подій". Що я НЕ розумію, це те, що визначає, чи "блокує" окрему операцію javascript, а не "блокує". Як я можу знати, від яких операцій я можу залежати, щоб синхронізувати результат для використання, який я використовуватиму в пізнішому коді, і які мені потрібно буде передавати зворотні дзвінки, щоб я міг обробити вихід після завершення початкової операції? Чи є десь список функцій Javascript, які є асинхронними / не блокуючими, і список тих, які синхронізуються / блокують? Що заважає моєму додатку Javascript бути однією з гігантських умов гонки?

Я знаю, що операції, які займають тривалий час, як операції вводу-виводу в операціях Node та AJAX в Інтернеті, вимагають, щоб вони були асинхронними і тому використовували зворотні виклики - але хто визначає, що кваліфікується як "тривалий час"? Чи є якийсь тригер у цих операціях, який видаляє їх із звичайної "черги подій"? Якщо ні, то чим вони відрізняються від простих операцій, таких як присвоєння значень змінним або циклічного перегляду через масиви, які, здається, ми можемо залежати від завершення синхронно?

Можливо, я навіть не думаю про це правильно - сподіваючись, що хтось зможе мене встановити прямо. Спасибі!


це те, що я виявив, що є дійсно корисним, хоча ваша відповідь на ваше запитання полягає в тому, що вам потрібно перевірити документацію, щоб з’ясувати, чи методи асинхронні.
Анастасіос Андронідіс

Відповіді:


13

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

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

Немає жодного способу сказати точно. Це має бути або прописано в документі для функції, або очевидно з того, як працює інтерфейс.

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


1
В якості додаткової примітки, деякі функції Javascript блокують і не блокують, залежно від їх параметрів. Наприклад, XMLHttpRequest.openмає булевий asyncпараметр, який контролює, чи є пізніший виклик sendасинхронним.
Брайан

Я просто не знайшов цю відповідь корисною і загалом пояснив.
Мехді Рааш

@MehdiRaash - Відповідь полягає в тому, що ви це з'ясували з документації або з інтерфейсу. Іншого шляху немає. Ось що це говорить. Не впевнений, що ще чекав. Чарівної відповіді кулі немає.
jfriend00

6

З того, що я розумію, ви не запитуєте про те, що слід зробити асинхронним, а як сказати, чи функція асинхронна.

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

Це єдиний цілком надійний спосіб.

Тепер для здогадки.

  • Якщо він приймає зворотний дзвінок або повертає обіцянку, він, ймовірно, асинхронний (я бачив винятки з цього правила)
  • Як правило, все, що стосується вводу-виводу (I / O) у node.js і загалом у JavaScript, робиться асинхронно (я також бачив винятки з цього правила)

4

Оскільки JavaScript є єдиним потоком всіх блоків обробки, поки не відбудеться одне з наступних

1) Поточне виконання запитує зовнішню службу, таку як запит вводу / виводу або мережевого запиту або запит веб-робітника

2) Виклик функції ставиться на таймер, який слід виконати пізніше

Немає списку функцій блокування / незаблокування. Ви повинні перевірити документацію.

Ваш додаток може зіткнутися з умовою перегонів, якщо кілька зовнішніх служб мають блокування на потоці javascript і намагаються отримати доступ до нього одночасно. Сучасні веб-переглядачі та двигун V8 справляються з цим, але ви можете зіткнутися з такою умовою перегонів, якщо використовуєте фонегап та пишете програми javascript для мобільних пристроїв. Підтримки не існує для вирішення цих умов гонки.

Як правило, припустімо блоки коду, якщо немає зворотного дзвінка. І навіть якщо є зворотний дзвінок, це не означає, що він не блокується.


-1

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

Усі методи вводу-виводу в стандартній бібліотеці Node.js забезпечують асинхронні версії, які не блокують, і приймають функції зворотного виклику. Деякі методи також мають аналоги блокування, які мають імена, які закінчуються синхронізацією.


1
як це вирішує питання? Дивіться, як відповісти
gnat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.