Розуміння синхронного та асинхронного JavaScript - частина 1. T
Синхронний і асинхронний є заплутаними поняттями в JavaScript, особливо для початківців. Дві або більше речей синхронний коли вони трапляються одночасно (синхронізовано) і асинхронні, коли вони цього не роблять (не синхронізовано).
Хоча ці визначення легко прийняти, це насправді складніше, ніж це виглядає. Треба враховувати що саме синхронізовано, і що ні.
Ви б, напевно, подзвонили б нормальний
функція в JavaScript синхронна, чи не так? А якщо це щось подібне setTimeout ()
або AJAX, з яким ви працюєте, ви називатимете його асинхронним, так? Що робити, якщо я це скажу обидва асинхронні?
Пояснити чому, ми повинні звернутися до пана X за допомогою.
Сценарій 1 - пан X намагається синхронність
Ось установка:
- Г-н Х - це той, хто може відповісти на складні питання і виконувати будь-яке запитане завдання.
- Єдиний спосіб зв'язатися з ним - це телефонний дзвінок.
- Які б ви не були питання або завдання, щоб просити допомоги пана Х, щоб його виконати; ви його називаєте.
- Г-н Х дає вам відповідь або завершує завдання зразу, і повідомляє зроблено.
- Ви опускаєте приймач, відчуваючи вміст і виходите на кіно.
Те, що ви щойно здійснили, - це синхронний (назад і вперед) зв'язок З паном Х. Він слухав, як ви задавали йому своє запитання, і ви слухали, коли він відповідав на нього.
Сценарій 2 - пан X не задоволений синхронністю
Оскільки пан X настільки ефективний, він починає отримувати багато інших дзвінків. Так що відбувається, коли ви називаєте його, але він вже зайнятий розмовляти з кимось іншим? Ви не зможете задати йому своє запитання - не до того, як він зможе прийняти ваш дзвінок. Все, що ви почуєте, є зайнятим тоном.
Отже, що може зробити пан Х, щоб боротися з цим?
Замість прийому дзвінків безпосередньо:
- Г-н Х наймає нового хлопця, пана М і дає йому автовідповідач для абонентів залишити повідомлення.
- Робота Містера М полягає в тому, щоб передати повідомлення від автовідповідача до пана X, коли він знає, що пан X повністю закінчив обробку всіх попередніх повідомлень і вже є безкоштовно взяти новий.
- Тепер, коли ви називаєте його, замість того, щоб отримувати зайнятий тон, ви можете залишити повідомлення для пана Х, то зачекайте, доки він подзвонить вам (поки немає фільму).
- Після того, як пан X зробить з усіма поставленими в чергу повідомлення, які він отримав перед вами, він розгляне вашу проблему, і передзвонимо Вам дати вам відповідь.
Тепер тут лежить питання: чи були дії до цих пір синхронні або асинхронні?
Це змішане. Коли ви залишили повідомлення, Містер X не слухав його, тому четверта комунікація була асинхронною.
Але, коли він відповів, Ви там слухали, котрий робить зворотний зв'язок синхронним.
Я сподіваюся, що тепер ви краще зрозуміли, як сприймається синхронність в умовах спілкування. Час, щоб принести JavaScript.
JavaScript - Асинхронна мова програмування
Коли хтось помічає асинхронний JavaScript, на що вони посилаються взагалі - це те, як ви можете залишити повідомлення для неї і не заблоковано ваш дзвінок з зайнятим тоном.
Виклики функцій ніколи не направляйте у JavaScript, вони буквально зроблені через повідомлення.
JavaScript використовує a черги повідомлень де проводяться вхідні повідомлення (або події). An подія-петля (диспетчер повідомлень) послідовно посилає ці повідомлення на стек викликів де відповідні функції повідомлень укладаються в рамки (функція аргументи та змінні) для виконання.
Стек викликів містить кадр виклику початкової функції та будь-які інші виклики для функцій через вкладені виклики поверх неї .
Коли повідомлення приєднується до черги, він чекає, доки стек виклику не буде порожній від усіх кадрів з попереднього повідомлення, і коли це відбувається, подія-петля вилучає попереднє повідомлення, і додає відповідні кадри поточного повідомлення до стека викликів.
Повідомлення чекає знову, поки не стане стек викликів порожній від власних відповідних кадрів (тобто виконання всіх укладених функцій закінчено), потім видаляється.
Розгляньте наступний код:
function foo () функція bar () foo (); функція baz () bar (); baz ();
Запускається функція baz ()
(у останньому рядку фрагмента коду), для чого повідомлення додається до черги, і коли цикл подій вибирає його, стек викликів починає укладання кадрів для baz ()
, бар ()
, і foo ()
у відповідних пунктах виконання.
Як тільки виконання функцій буде завершено один за одним, їх кадри видалено з стека викликів, під час надсилання повідомлення все ще чекає в черзі, до baz ()
виводиться зі стека.
Пам'ятайте, що виклики функцій ніколи не направляйте у JavaScript, вони зроблені через повідомлення. Тому, коли ви чуєте, як хтось каже, що сам JavaScript є мовою асинхронного програмування, припустимо, що вони говорять про його вбудований “автовідповідач”, і як ви можете залишати повідомлення.
А як щодо специфічних асинхронних методів?
До цих пір я не торкнувся таких API, як setTimeout ()
і AJAX, це ті, які є конкретно називають асинхронними. Чому так?
Важливо розуміти, що саме є синхронним або асинхронним. JavaScript, за допомогою подій і циклу подій, може практикувати асинхронна обробка повідомлень, але це не означає все в JavaScript асинхронний.
Пам'ятайте, я сказав вам, що повідомлення не залишилося, поки стек виклику не був порожній від відповідних кадрів, так само, як ви не пішли на кіно, поки ви не отримали свою відповідь - це синхронний, Ви там чекаєте до завершення завдання, і ви отримаєте відповідь.
Очікування не є ідеальним у всіх сценаріях. Що робити, якщо після залишення повідомлення, замість того, щоб чекати, ви можете залишити фільм? Що робити, якщо функція може вийти з ладу (спорожнення стека викликів), і його повідомлення може бути вилучено ще до того, як завдання функції буде завершено? Що робити, якщо код може бути виконаний асинхронно?
Ось тут такі API, як setTimeout ()
і AJAX приходять в картину, і те, що вони роблять, це… триматися, я не можу пояснити це без повернення до пана X, який ми побачимо у другій частині цієї статті. Залишайтеся з нами.