Андрей Кулешов




Асинхронный
JavaScript
Про стоящих в очереди и отсроченные обещания
Почему JavaScript вновь удивляет Си-
программистов...


▪ То, чему нас учили в институте
▪ Почему в яваскрипт всѐ совсем по другому.
Карта выполнения кода в Си-подобных
языках
                     ▪ Исполнение нашего кода может
                       быть прервано в любое время
                       соседним потоком кода
                     ▪ Чтобы безопасно использовать
                       несколько потоков, мы изучали
                       мьютексы, семафоры...
Карта выполнения JavaScript в web-браузерах




                           Посмотрели,
   Получили   Выполнили                  Остановили
                           есть ли ещѐ
    задачу      задачу                     работу
                             задачи



              Повторили.
Очередь выполнения
▪ Когда выполняется код JavaScript – он не может быть прерван никаким
  другим кодом
▪ Мы можем только уведомить движок, что мы хотели бы выполнить
  некоторый новый кусок кода, и поставить его в очередь выполнения
▪ Постановка в очередь выполнения – операция достаточно дорогая; кроме
  того, в браузерах ни при каких условиях не возможно мгновенное
  выполнение поставленного в очередь кода
Кто может ставить код в очередь?
▪ Пришедшие к браузеру из внешнего мира события:


- пришедший запрос (ответ) по сети
- события от пользователя (щелчки мышью, клавиатурный ввод... многое)
Событие перерисоки браузера – стоит в той же очереди (хотя, в современных
браузерах, и со значительно большим приоритетом)
▪ Из кода javascript:


- setTimeout, setInterval
Как работает setTimeout
▪ Не так, как в си-языках 
▪ Код внутри таймаута не выполняется через заданное время, а ставится в
  очередь выполенения. А выполняется, соответственно, по возможности.
▪ Код внутри setTimeout выполняется асинхронно, превращая вызывающую
  функцию в целом в асинхронную
Ну... это здорово?..
▪ В сферическом вакууме модель исполения яваскрипта была бы идеальной
▪ Большой плохой момент - взаимодействие с пользователем живет в том же
  самом потоке
▪ Пока выполняется JavaScript код – не будет производиться никакая
  отрисовка страницы (хотя современные браузеры зачастую всѐ же пытаются
  что-то рисовать...)
▪ Но уж совершенно точно не будут выполняться никакие события
  пользовательского интерфейса
Асинхронные функции
▪ Функция называется асинхронной, когда она откладывает своѐ выполнение
  (или выполнение следующих действий) и ставит его в очередь задач
▪ Наш код, который мы хотим выполнить после окончания функции Х,
  передается в функции Х как функция обратного вызова (callback)
Когда функции становятся асинхронными:
▪ В первую очередь –               ▪ Синхронная
  взаимодействующие с внешним        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);
                                     });
Асинхронный однажды – асинхронный всегда
▪ Всѐ функции, укушенные асинхронной функцией, сами становятся
  асинхронными
▪ Нет никакого пути вернуть асинхронную функцию в неасинхронный режим
Демо



▪ setTimeout(0)
▪ setTimeout(500) и цикл длиной в секунду
▪ создание большого количества элементов в синхронном режиме, в
  асинхронном режиме – поэлементно и в асинхронном режиме - группами
Шаблон отложенных обещаний
▪ deferred – шаблон проектирования javascipt кода
▪ Суть в двух словах: есть некоторое событие; когда оно выполнено – нужно
  выполнить наши обработчики этого события
▪ И нам неважно, наступило ли уже это событие или ещѐ нет
▪ Но нам обещают, что как только станет можно – нас позовут
jQuery $.Deffered
▪   Можно подписаться на его события
-   always
-   done
-   fail
▪ Им можно управлять
- resolve
- reject
▪ У него можно получить объект promise (“обещание”)
  у него такие же события, но им нельзя управлять
  Он нужн для того, чтобы отдать его наружу, из нашего класса, чтобы на него
  могли подписаться, но никто не мог управлять поведением вместо нас
Будет ли в JavaScript классическая
многопоточность?
▪ Нет, насколько это зависит от комитета ECMA
▪ Workers – единственная альтернатива в ближайшее время
Workers
▪ Отдельный файл с JavaScript-кодом, который может быть запущен в
  отдельном потоке
▪ Обмен данными с вызывающим кодом – только через механизм сообщений
  (подписка на события)
▪ Воркер не имеет доступа к вызывающему контексту (переменные и т.п.), не
  имеет доступа к DOM страницы
Есть ещѐ Node.js…
Но для докладчика это Terra Incognita
Интересное чтение
▪ 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
Вопросы?
                 Внимательно слушаю! 


Андрей Кулешов

kaa-tula@ya.ru
    akuleshov.tula




Специально для http://GetDev.NET

Async Javascript

  • 1.
    Андрей Кулешов Асинхронный 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 страницы
  • 17.
    Есть ещѐ Node.js… Нодля докладчика это Terra Incognita
  • 18.
    Интересное чтение ▪ Eventloops 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.
    Вопросы? Внимательно слушаю!  Андрей Кулешов [email protected] akuleshov.tula Специально для http://GetDev.NET