Оскільки JavaScript запускається в один потік, після запиту AJAX, що насправді відбувається у фоновому режимі? Я хотів би глибше зрозуміти це, чи може хтось пролити трохи світла?
Оскільки JavaScript запускається в один потік, після запиту AJAX, що насправді відбувається у фоновому режимі? Я хотів би глибше зрозуміти це, чи може хтось пролити трохи світла?
Відповіді:
Під обкладинками у javascript є черга подій. Кожен раз, коли завершується виконання потоку javascript, він перевіряє, чи є ще одна подія в черзі на обробку. Якщо є, він витягує його з черги і запускає цю подію (наприклад, натискання миші).
Натуральна мережа коду, що лежить під викликом ajax, буде знати, коли буде виконано відповідь ajax, і подія буде додана до черги подій javascript. Від того, наскільки власний код знає, коли виконується виклик ajax, залежить від реалізації. Він може бути реалізований за допомогою потоків, а також може бути сам подій (це насправді не має значення). Сенс реалізації полягає в тому, що коли відповідь на ajax виконана, якийсь нативний код буде знати, що це зроблено, і покладе подію в чергу JS.
Якщо в даний час не працює Javascript, подія буде негайно запущена, що запустить обробник відповіді ajax. Якщо в цей час щось запущено, подія буде оброблена після завершення поточного потоку JavaScript. Двигун javascript не повинен проводити жодного опитування. Коли фрагмент Javascript закінчує виконувати, двигун JS просто перевіряє чергу подій, щоб побачити, чи є ще щось, що потрібно запустити. Якщо це так, він вискакує наступну подію з черги та виконує її (викликає одну або кілька функцій зворотного виклику, які зареєстровані для цієї події). Якщо нічого не стоїть у черзі подій, то інтерпретатор JS має вільний час (збирання сміття або простою), поки якийсь зовнішній агент не поставить щось інше у чергу подій та знову його прокине.
Оскільки всі зовнішні події проходять через чергу подій, і жодна подія ніколи не спрацьовує, поки javascript фактично працює щось інше, він залишається єдиним потоком.
Ось кілька статей про деталі:
.focus()
елемент, і це викликає пару інших подій, таких як подія "розмиття" на об'єкті з фокусом. Ця подія розмивання відбувається синхронно і не проходить через чергу подій, тому це станеться безпосередньо перед іншими речами, які можуть бути у черзі подій. На практиці я ніколи не вважав, що це викликає практичне занепокоєння.
Ви можете знайти тут дуже повну документацію про події обробки в JavaScript.
Він написаний хлопцем, який працює над реалізацією javascript у браузері Opera.
Точніше, подивіться на заголовки: "Потік подій", "Черга подій" та "Події, що не користувачі": ви дізнаєтесь, що:
Примітка. Оригінальним посиланням було: посилання , але воно тепер мертве.
Хочу трохи детальніше розповісти про реалізацію ajax, згадану у відповідях.
Хоча (звичайний) виконання Javascript є НЕ багато-- як зазначено також в наведених вище відповідей - тим НЕ менш , реальне поводження з AJAX responses
(а також обробки запитів) є НЕ Javascript, і це - як правило , - це багато-. (див. реалізацію джерела хромування XMLHttpRequest, про який ми поговоримо вище)
і я поясню, візьмемо наступний код:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- після кроку 1), тоді, поки ваш js-код триває виконання (крок 2 і після), браузер починає справжню роботу: 1. форматування запиту tcp 2. відкриття сокета 3. надсилання заголовків 4. рукостискання 5. надсилання тіло 6. відповідь очікування 7. заголовки читання 8. тіло зчитування тощо. вся ця реалізація зазвичай виконується в іншому потоці паралельно виконанню коду js. Наприклад, згадана реалізація хрому використовує Threadable Loader, що переходить до 😉, (також можна скласти враження, переглянувши вкладку мережі завантаження сторінки, ви побачите кілька одночасних запитів).
на закінчення я б сказав, що - принаймні, більшість ваших операцій вводу / виводу можна зробити одночасно / асинхронізувати (і ви можете скористатися цим, використовуючи, наприклад, очікування ). але вся взаємодія з цими операціями (видача, виконання js зворотного виклику) всі синхронні.