Материалы с доклада: http://getdev.net/Event/async-javascript
Рассказ о том, как работает асинхронность в JavaScript, кто стоит в очереди выполнения, почему в JavaScript никогда не будет процессорной гонки, как давать отсроченные обещания и что делать, если одна из ваших функций подхватила заразу асинхронности
2. Почему JavaScript вновь удивляет Си-
программистов...
▪ То, чему нас учили в институте
▪ Почему в яваскрипт всѐ совсем по другому.
3. Карта выполнения кода в Си-подобных
языках
▪ Исполнение нашего кода может
быть прервано в любое время
соседним потоком кода
▪ Чтобы безопасно использовать
несколько потоков, мы изучали
мьютексы, семафоры...
4. Карта выполнения JavaScript в web-браузерах
Посмотрели,
Получили Выполнили Остановили
есть ли ещѐ
задачу задачу работу
задачи
Повторили.
5. Очередь выполнения
▪ Когда выполняется код JavaScript – он не может быть прерван никаким
другим кодом
▪ Мы можем только уведомить движок, что мы хотели бы выполнить
некоторый новый кусок кода, и поставить его в очередь выполнения
▪ Постановка в очередь выполнения – операция достаточно дорогая; кроме
того, в браузерах ни при каких условиях не возможно мгновенное
выполнение поставленного в очередь кода
6. Кто может ставить код в очередь?
▪ Пришедшие к браузеру из внешнего мира события:
- пришедший запрос (ответ) по сети
- события от пользователя (щелчки мышью, клавиатурный ввод... многое)
Событие перерисоки браузера – стоит в той же очереди (хотя, в современных
браузерах, и со значительно большим приоритетом)
▪ Из кода javascript:
- setTimeout, setInterval
7. Как работает setTimeout
▪ Не так, как в си-языках
▪ Код внутри таймаута не выполняется через заданное время, а ставится в
очередь выполенения. А выполняется, соответственно, по возможности.
▪ Код внутри setTimeout выполняется асинхронно, превращая вызывающую
функцию в целом в асинхронную
8. Ну... это здорово?..
▪ В сферическом вакууме модель исполения яваскрипта была бы идеальной
▪ Большой плохой момент - взаимодействие с пользователем живет в том же
самом потоке
▪ Пока выполняется JavaScript код – не будет производиться никакая
отрисовка страницы (хотя современные браузеры зачастую всѐ же пытаются
что-то рисовать...)
▪ Но уж совершенно точно не будут выполняться никакие события
пользовательского интерфейса
9. Асинхронные функции
▪ Функция называется асинхронной, когда она откладывает своѐ выполнение
(или выполнение следующих действий) и ставит его в очередь задач
▪ Наш код, который мы хотим выполнить после окончания функции Х,
передается в функции Х как функция обратного вызова (callback)
10. Когда функции становятся асинхронными:
▪ В первую очередь – ▪ Синхронная
взаимодействующие с внешним function load() {
миром (читай – AJAX) var data = //(идём на сервер)
//курим, ждём ответа
▪ Во вторую очередь – функции return data ;
реакции на события от }
пользователя var result = load();
print(result)
▪ В третью очередь –
долговременные функции, ▪ Асинхронная
блокирующие взаимодействие с function load(callback) {
пользователем – мы сами делаем var data =
их асинхронными goToServerBrowserFunction(
callback);
//и там внутри происходит
//callback(someData)
}
load(function (result) {
print(result);
});
11. Асинхронный однажды – асинхронный всегда
▪ Всѐ функции, укушенные асинхронной функцией, сами становятся
асинхронными
▪ Нет никакого пути вернуть асинхронную функцию в неасинхронный режим
12. Демо
▪ setTimeout(0)
▪ setTimeout(500) и цикл длиной в секунду
▪ создание большого количества элементов в синхронном режиме, в
асинхронном режиме – поэлементно и в асинхронном режиме - группами
13. Шаблон отложенных обещаний
▪ deferred – шаблон проектирования javascipt кода
▪ Суть в двух словах: есть некоторое событие; когда оно выполнено – нужно
выполнить наши обработчики этого события
▪ И нам неважно, наступило ли уже это событие или ещѐ нет
▪ Но нам обещают, что как только станет можно – нас позовут
14. jQuery $.Deffered
▪ Можно подписаться на его события
- always
- done
- fail
▪ Им можно управлять
- resolve
- reject
▪ У него можно получить объект promise (“обещание”)
у него такие же события, но им нельзя управлять
Он нужн для того, чтобы отдать его наружу, из нашего класса, чтобы на него
могли подписаться, но никто не мог управлять поведением вместо нас
15. Будет ли в JavaScript классическая
многопоточность?
▪ Нет, насколько это зависит от комитета ECMA
▪ Workers – единственная альтернатива в ближайшее время
16. Workers
▪ Отдельный файл с JavaScript-кодом, который может быть запущен в
отдельном потоке
▪ Обмен данными с вызывающим кодом – только через механизм сообщений
(подписка на события)
▪ Воркер не имеет доступа к вызывающему контексту (переменные и т.п.), не
имеет доступа к DOM страницы
18. Интересное чтение
▪ Event loops in JS specification
▪ Async JavaScript: Build More Responsive Apps with Less Code by Trevor
Burnham
▪ High Performance JavaScript by Nicholas C. Zakas
▪ StackOverflow – exceptions from the rule
19. Вопросы?
Внимательно слушаю!
Андрей Кулешов
kaa-tula@ya.ru
akuleshov.tula
Специально для http://GetDev.NET