SlideShare una empresa de Scribd logo
1 de 36
Descargar para leer sin conexión
Михаил Давыдов
Разработчик JavaScript
JavaScript
Асинхронность
3
Задача
•  Качаем 1 файл
•  После отправляем данные на 2 сервера
•  Синхронизируемся
4
Сделаем обертку над XMLHttpRequest
function syncXHR(method, url, data) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, false);
xhr.send(data);
return xhr.responseText;
}
Синхронный код
var data = syncXHR('GET', ‘http://host1/page.json’);
data = processData(data);
syncXHR(‘POST’, ‘http://host2/result/’, data);
syncXHR(‘POST’, ‘http://host3/result/’, data);
alert(‘Done!’);
5
Схема загрузки
время
БлокировкаБлокировка Блокировка
Запрос Запрос Запрос
Подготовка Обработка Отправка Алерт
6
Сделаем обертку над XMLHttpRequest
Асинхронный код
function asyncXHR(method, url, data, callback) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, xhr.responseText);
} else {
callback(‘error’);
}
}
}
xhr.send(data);
}
7
Сам код. Изменилось все.
Асинхронный код
asyncXHR ('GET', ‘http://host1/page.json’, null,
function (err, data) {
data = processData(data);
var counter = 2;
function done(err, data) {
counter--;
if (!counter) alert(‘Done!’);
}
asyncXHR(‘POST’, ‘http://host2/result/’, data, done);
asyncXHR(‘POST’, ‘http://host3/result/’, data, done);
});
8
Схема загрузки
время
Ожидание Ожидание
Запрос
Подготовка Обработка Отправка Алерт
9
Асинхронность
•  Производительность
–  Код выше
•  Интерфейс пользователя
•  Проблемы
–  Много лишнего шума
–  Проблема синхронизации
–  Куча вложенных колбэков: Pyramid of Doom
•  Несколько реализаций
–  Event Loop
10
Event Loop
•  Основа всех событийных систем
•  Использует очередь событий
•  Ждет события
•  Выполняет события из очереди
–  События в очередь поступают во время выполнения событий
–  События генерируют события
•  Завершается когда очередь пуста
Паттерны
Callback,
Event,
Promise,
Deferred
12
Типичный пример – обертка над XMLHttpRequest
Callback
function asyncXHR(method, url, data, callback) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, xhr.responseText);
} else {
callback(‘error’);
}
}
}
xhr.send(data);
}
13
Callback
•  Самый простой вариант
–  Дешевая абстракция
•  В него могут приходить ошибки и данные
–  cтиль node.js
–  callback(err, data)
14
Общая схема
Event: EventEmitter, PubSub
function EventEmitter () {
this.events = {};
}
EventEmitter.prototype = {
on: function (event, callback) {},
off: function (event, callback) {},
emit: function (event, data) {}
};
http://nodejs.org/api/events.html
15
Типичный пример – обертка над XMLHttpRequest
Event
function eventXHR(method, url, data) {
var xhr = new XMLHttpRequest(),
event = new EventEmitter();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
event.emit(‘data’, xhr.responseText);
} else {
event.emit(‘error’);
}
}
}
xhr.send(data);
return event;
}
16
Сам код. Изменилось не так много.
Event
eventXHR('GET', ‘http://host1/page.json’)
.on(‘data’, function (data) {
data = processData(data);
var counter = 2;
function done() {
counter--;
if (!counter) alert(‘Done!’);
}
eventXHR(‘POST’, ‘http://host2/result/’, data)
.on(‘data’, done);
eventXHR(‘POST’, ‘http://host3/result/’, data)
.on(‘data’, done);
})
.on(‘error’, function(){ });
17
Event
•  Абстракция более высокого уровня
•  Ошибки отделены от данных
–  Возможны логически разные типы данных
•  Можно отписаться от события
•  Можно подписаться несколько раз
•  Можно передавать как аргумент
18
Promise
•  Это Обещанные данные
•  Имеет 3 состояния
–  Не выполнен (выполняется)
–  Выполнен (результат)
–  Отклонен (ошибка)
•  Меняет состояние только 1 раз
–  В событиях состояние меняется сколько угодно раз
•  Запоминает свое состояние
–  В отличии от события в котором состояние – это поток
http://wiki.commonjs.org/wiki/Promises
19
Общая схема
Promise
function Promise () {
this.isFulfilled = false;
this.isRejected = false;
this.isResolved = false;
this.result = null;
}
Promise.prototype = {
then: function (fulfilled, rejected, progressed) {},
reject: function (error) {},
resolve: function (data) {}
};
20
Типичный пример – обертка над XMLHttpRequest
Promise
function promiseXHR(method, url, data) {
var xhr = new XMLHttpRequest(),
promise = new Promise();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
promise.resolve(xhr.responseText);
} else {
promise.reject(‘Error ’ + xhr.status);
}
}
}
xhr.send(data);
return promise;
}
21
Сам код
Promise
promiseXHR('GET', ‘http://host1/page.json’)
.then(function (data) {
data = processData(data);
var promises = [
promiseXHR(‘POST’, ‘http://host2/result/’, data),
promiseXHR(‘POST’, ‘http://host3/result/’, data)
];
when(promises, function (data) {
alert(‘Done!’);
});
});
22
Promise
•  Запоминает свое состояние
•  Всегда возвращает один результат
–  В отличие от события где данные – поток
–  Не зависит от времени опроса
•  Можно передавать как аргумент
•  Можно выполнять операции
–  then
23
Deferred
•  Это защищенный Promise
•  Разграничивает слушателя и Promise
•  Слушатель не может вмешаться
–  С чистыми промисами можно завершить промис на слушателе
–  Меньше логических ошибок
http://api.jquery.com/category/deferred-object/
24
Общая схема
Deferred
function Deferred () {
this._promise = {
then: function (fulfilled, rejected, progressed) {}
};
}
Deferred.prototype = {
promise: function (error) {
return this._promise;
},
reject: function (error) {},
resolve: function (data) {}
};
25
Типичный пример – обертка над XMLHttpRequest
Deferred
function defferedXHR(method, url, data) {
var xhr = new XMLHttpRequest(),
deferred = new Deffered();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
deferred.resolve(xhr.responseText);
} else {
deferred.reject(‘Error ’ + xhr.status);
}
}
}
xhr.send(data);
return deferred.promise();
}
26
Сам код
Deferred
defferedXHR('GET', ‘http://host1/page.json’)
.then(function (data) {
data = processData(data);
var promises = [
defferedXHR(‘POST’, ‘http://host2/result/’, data),
defferedXHR(‘POST’, ‘http://host3/result/’, data)
];
when(promises, function (data) {
alert(‘Done!’);
});
})
.reject(‘Mua-ha-ha!’); // Это сделать нельзя
Библиотеки
Streamlinejs,
Fibers
Step,
Q
28
Streamline – попытка избавится от асинхронного шума
Используют callback(err, data)
Streamline
var data = asyncXHR('GET', '/', null, _);
asyncXHR('POST', '/', data, _);
asyncXHR('POST', '/', data, _);
alert('Done!');
https://github.com/Sage/streamlinejs
29
Happy Debug!
Streamline – результат генерации
(function main(_) {
var data;
var __frame = {
name: "main”,
line: 1
};
return __func(_, this, arguments, main, 0, __frame, function __$main() {
return asyncXHR("GET", "/", null, __cb(_, __frame, 17, 11, function ___(__0, __1) {
data = __1;
return asyncXHR("POST", "/", data, __cb(_, __frame, 18, 0, function __$main() {
return asyncXHR("POST", "/", data, __cb(_, __frame, 19, 0, function __$main() {
alert("Done!");
_();
}, true));
}, true));
}, true));
});
}).call(this, __trap);
30
Streamlinejs
•  Генерация кода – результат ужасен!
•  Шум из массы _
•  Его цель – выполнять асинхронный код
последовательно
31
Fibers – попытка избавится от асинхронного шума
Используют callback(err, data)
Fibers
var Future = require('fibers/future'),
wait = Future.wait;
var asyncXHR = Future.wrap(asyncXHR);
Fiber(function () {
var data = asyncXHR(‘GET’, '...’, null).wait();
data = processData(data);
asyncXHR(‘POST’, '...’, data).wait();
asyncXHR(‘POST’, '...’, data).wait();
alert(‘Done!’);
}).run();
https://github.com/laverdet/node-fibers	

https://github.com/0ctave/node-sync
32
Fibers
•  Особая версия Node.js
–  Хак механизма yield()
•  Похожи на треды
–  Не могут прерываться где угодно процессором
–  Меньше расходов на «безопасные зоны»
•  Похожи на Event Loop
–  yield() и ручное прерывание фибера
–  Блокировка остальных фиберов
–  Нет реального параллелизма (не занимают все ядра процессора)
•  Параллельные запросы последовательно
–  Необходимо использовать дополнительные функции
33
Позволяет выполнять асинхронный код в синхронном стиле
Работает с callback(err, data)
Step
Step(
function () {
asyncXHR('GET’, ‘...’, null, this);
},
function (err, data) {
return processData(data);
},
function (err, data) {
asyncXHR(‘POST’, ‘...’, data, this.parallel());
asyncXHR(‘POST’, ‘...’, data, this.parallel());
},
function (err, result1, result2) {
alert(‘Done!’);
}
);
https://github.com/creationix/step
34
Работает с Promise
Представляет интерфейс для работы с промисами
Q
var data = promiseXHR('GET', '...');
data.than(processAndSendData).than(function () {
alert(‘Done!’);
});
function processAndSendData(data) {
data = processData(data);
return sendData(data);
}
function sendData(data) {
return Q.all([
promiseXHR(‘POST’, ‘...’, data),
promiseXHR(‘POST’, ‘...’, data)
]);
}
https://github.com/kriskowal/q
35
Асинхронность
•  Событийный ввод-вывод
•  Работа с GUI
•  Паттерны
–  Callback
–  EventEmitter
–  Promise
–  Deferred
•  Хаки
–  Streamline
–  Fibers
•  Библиотеки
–  Step
–  Q
Михаил Давыдов
Разработчик JavaScript
azproduction@yandex-team.ru
azproduction
Спасибо

Más contenido relacionado

La actualidad más candente

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
Dmitry Soshnikov
 
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
Конференция разработчиков программного обеспечения SECON'2014
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
Technopark
 
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Alexey Lesovsky
 

La actualidad más candente (20)

Javascript
JavascriptJavascript
Javascript
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart GammaMongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORM
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
 
JavaDay'14
JavaDay'14JavaDay'14
JavaDay'14
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
 
Подводные камни System.Security.Cryptography
Подводные камни System.Security.CryptographyПодводные камни System.Security.Cryptography
Подводные камни System.Security.Cryptography
 
Подводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IПодводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, I
 
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.
 
msumobi2. Лекция 2
msumobi2. Лекция 2msumobi2. Лекция 2
msumobi2. Лекция 2
 

Similar a JavaScript. Async (in Russian)

Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, Ajax
Yandex
 
Mihail davidov js-ajax
Mihail davidov js-ajaxMihail davidov js-ajax
Mihail davidov js-ajax
Yandex
 
Web весна 2013 лекция 9
Web весна 2013 лекция 9Web весна 2013 лекция 9
Web весна 2013 лекция 9
Technopark
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
AndreyGeonya
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
yaevents
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4
Technopark
 
Web весна 2012 лекция 9
Web весна 2012 лекция 9Web весна 2012 лекция 9
Web весна 2012 лекция 9
Technopark
 
FPUG Dzyga presentation
FPUG Dzyga presentationFPUG Dzyga presentation
FPUG Dzyga presentation
Ivan Filimonov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
etyumentcev
 

Similar a JavaScript. Async (in Russian) (20)

Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, Ajax
 
Mihail davidov js-ajax
Mihail davidov js-ajaxMihail davidov js-ajax
Mihail davidov js-ajax
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
Web весна 2013 лекция 9
Web весна 2013 лекция 9Web весна 2013 лекция 9
Web весна 2013 лекция 9
 
Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)
 
Reactive extensions
Reactive extensionsReactive extensions
Reactive extensions
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutines
 
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
 
course js day 2
course js day 2course js day 2
course js day 2
 
Суперсилы Chrome developer tools
Суперсилы Chrome developer toolsСуперсилы Chrome developer tools
Суперсилы Chrome developer tools
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4
 
Web весна 2012 лекция 9
Web весна 2012 лекция 9Web весна 2012 лекция 9
Web весна 2012 лекция 9
 
FPUG Dzyga presentation
FPUG Dzyga presentationFPUG Dzyga presentation
FPUG Dzyga presentation
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 

Más de Mikhail Davydov

JavaScript. Event Model (in russian)
JavaScript. Event Model (in russian)JavaScript. Event Model (in russian)
JavaScript. Event Model (in russian)
Mikhail Davydov
 
Ajax and Transports (in russian)
Ajax and Transports (in russian)Ajax and Transports (in russian)
Ajax and Transports (in russian)
Mikhail Davydov
 
Introduction in Node.js (in russian)
Introduction in Node.js (in russian)Introduction in Node.js (in russian)
Introduction in Node.js (in russian)
Mikhail Davydov
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)
Mikhail Davydov
 
JavaScript. OOP (in russian)
JavaScript. OOP (in russian)JavaScript. OOP (in russian)
JavaScript. OOP (in russian)
Mikhail Davydov
 
JavaScript. Event Loop and Timers (in russian)
JavaScript. Event Loop and Timers (in russian)JavaScript. Event Loop and Timers (in russian)
JavaScript. Event Loop and Timers (in russian)
Mikhail Davydov
 
Modules and assembling of JavaScript (in russian)
Modules and assembling of JavaScript (in russian)Modules and assembling of JavaScript (in russian)
Modules and assembling of JavaScript (in russian)
Mikhail Davydov
 
JavaScript. Introduction (in russian)
JavaScript. Introduction (in russian)JavaScript. Introduction (in russian)
JavaScript. Introduction (in russian)
Mikhail Davydov
 
JavaScript. Basics (in russian)
JavaScript. Basics (in russian)JavaScript. Basics (in russian)
JavaScript. Basics (in russian)
Mikhail Davydov
 
JavaScript on frontend and backend (in Russian
JavaScript on frontend and backend (in RussianJavaScript on frontend and backend (in Russian
JavaScript on frontend and backend (in Russian
Mikhail Davydov
 
Making Scalable JavaScript Application
Making Scalable JavaScript ApplicationMaking Scalable JavaScript Application
Making Scalable JavaScript Application
Mikhail Davydov
 

Más de Mikhail Davydov (16)

Components now! (in russian)
Components now! (in russian)Components now! (in russian)
Components now! (in russian)
 
JavaScript. Event Model (in russian)
JavaScript. Event Model (in russian)JavaScript. Event Model (in russian)
JavaScript. Event Model (in russian)
 
Code Style (in russian)
Code Style (in russian)Code Style (in russian)
Code Style (in russian)
 
Ajax and Transports (in russian)
Ajax and Transports (in russian)Ajax and Transports (in russian)
Ajax and Transports (in russian)
 
Introduction in Node.js (in russian)
Introduction in Node.js (in russian)Introduction in Node.js (in russian)
Introduction in Node.js (in russian)
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)
 
JavaScript. OOP (in russian)
JavaScript. OOP (in russian)JavaScript. OOP (in russian)
JavaScript. OOP (in russian)
 
JavaScript. Event Loop and Timers (in russian)
JavaScript. Event Loop and Timers (in russian)JavaScript. Event Loop and Timers (in russian)
JavaScript. Event Loop and Timers (in russian)
 
Modules and assembling of JavaScript (in russian)
Modules and assembling of JavaScript (in russian)Modules and assembling of JavaScript (in russian)
Modules and assembling of JavaScript (in russian)
 
JavaScript. Introduction (in russian)
JavaScript. Introduction (in russian)JavaScript. Introduction (in russian)
JavaScript. Introduction (in russian)
 
JavaScript. Basics (in russian)
JavaScript. Basics (in russian)JavaScript. Basics (in russian)
JavaScript. Basics (in russian)
 
JavaScript on frontend and backend (in Russian
JavaScript on frontend and backend (in RussianJavaScript on frontend and backend (in Russian
JavaScript on frontend and backend (in Russian
 
Components now!
Components now! Components now!
Components now!
 
Dump-IT Загрузка и инициализация JavaScript
Dump-IT Загрузка и инициализация JavaScriptDump-IT Загрузка и инициализация JavaScript
Dump-IT Загрузка и инициализация JavaScript
 
Dart - светлая сторона силы?
Dart - светлая сторона силы?Dart - светлая сторона силы?
Dart - светлая сторона силы?
 
Making Scalable JavaScript Application
Making Scalable JavaScript ApplicationMaking Scalable JavaScript Application
Making Scalable JavaScript Application
 

JavaScript. Async (in Russian)

  • 1.
  • 3. 3 Задача •  Качаем 1 файл •  После отправляем данные на 2 сервера •  Синхронизируемся
  • 4. 4 Сделаем обертку над XMLHttpRequest function syncXHR(method, url, data) { var xhr = new XMLHttpRequest(); xhr.open(method, url, false); xhr.send(data); return xhr.responseText; } Синхронный код var data = syncXHR('GET', ‘http://host1/page.json’); data = processData(data); syncXHR(‘POST’, ‘http://host2/result/’, data); syncXHR(‘POST’, ‘http://host3/result/’, data); alert(‘Done!’);
  • 5. 5 Схема загрузки время БлокировкаБлокировка Блокировка Запрос Запрос Запрос Подготовка Обработка Отправка Алерт
  • 6. 6 Сделаем обертку над XMLHttpRequest Асинхронный код function asyncXHR(method, url, data, callback) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { callback(null, xhr.responseText); } else { callback(‘error’); } } } xhr.send(data); }
  • 7. 7 Сам код. Изменилось все. Асинхронный код asyncXHR ('GET', ‘http://host1/page.json’, null, function (err, data) { data = processData(data); var counter = 2; function done(err, data) { counter--; if (!counter) alert(‘Done!’); } asyncXHR(‘POST’, ‘http://host2/result/’, data, done); asyncXHR(‘POST’, ‘http://host3/result/’, data, done); });
  • 9. 9 Асинхронность •  Производительность –  Код выше •  Интерфейс пользователя •  Проблемы –  Много лишнего шума –  Проблема синхронизации –  Куча вложенных колбэков: Pyramid of Doom •  Несколько реализаций –  Event Loop
  • 10. 10 Event Loop •  Основа всех событийных систем •  Использует очередь событий •  Ждет события •  Выполняет события из очереди –  События в очередь поступают во время выполнения событий –  События генерируют события •  Завершается когда очередь пуста
  • 12. 12 Типичный пример – обертка над XMLHttpRequest Callback function asyncXHR(method, url, data, callback) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { callback(null, xhr.responseText); } else { callback(‘error’); } } } xhr.send(data); }
  • 13. 13 Callback •  Самый простой вариант –  Дешевая абстракция •  В него могут приходить ошибки и данные –  cтиль node.js –  callback(err, data)
  • 14. 14 Общая схема Event: EventEmitter, PubSub function EventEmitter () { this.events = {}; } EventEmitter.prototype = { on: function (event, callback) {}, off: function (event, callback) {}, emit: function (event, data) {} }; http://nodejs.org/api/events.html
  • 15. 15 Типичный пример – обертка над XMLHttpRequest Event function eventXHR(method, url, data) { var xhr = new XMLHttpRequest(), event = new EventEmitter(); xhr.open(method, url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { event.emit(‘data’, xhr.responseText); } else { event.emit(‘error’); } } } xhr.send(data); return event; }
  • 16. 16 Сам код. Изменилось не так много. Event eventXHR('GET', ‘http://host1/page.json’) .on(‘data’, function (data) { data = processData(data); var counter = 2; function done() { counter--; if (!counter) alert(‘Done!’); } eventXHR(‘POST’, ‘http://host2/result/’, data) .on(‘data’, done); eventXHR(‘POST’, ‘http://host3/result/’, data) .on(‘data’, done); }) .on(‘error’, function(){ });
  • 17. 17 Event •  Абстракция более высокого уровня •  Ошибки отделены от данных –  Возможны логически разные типы данных •  Можно отписаться от события •  Можно подписаться несколько раз •  Можно передавать как аргумент
  • 18. 18 Promise •  Это Обещанные данные •  Имеет 3 состояния –  Не выполнен (выполняется) –  Выполнен (результат) –  Отклонен (ошибка) •  Меняет состояние только 1 раз –  В событиях состояние меняется сколько угодно раз •  Запоминает свое состояние –  В отличии от события в котором состояние – это поток http://wiki.commonjs.org/wiki/Promises
  • 19. 19 Общая схема Promise function Promise () { this.isFulfilled = false; this.isRejected = false; this.isResolved = false; this.result = null; } Promise.prototype = { then: function (fulfilled, rejected, progressed) {}, reject: function (error) {}, resolve: function (data) {} };
  • 20. 20 Типичный пример – обертка над XMLHttpRequest Promise function promiseXHR(method, url, data) { var xhr = new XMLHttpRequest(), promise = new Promise(); xhr.open(method, url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { promise.resolve(xhr.responseText); } else { promise.reject(‘Error ’ + xhr.status); } } } xhr.send(data); return promise; }
  • 21. 21 Сам код Promise promiseXHR('GET', ‘http://host1/page.json’) .then(function (data) { data = processData(data); var promises = [ promiseXHR(‘POST’, ‘http://host2/result/’, data), promiseXHR(‘POST’, ‘http://host3/result/’, data) ]; when(promises, function (data) { alert(‘Done!’); }); });
  • 22. 22 Promise •  Запоминает свое состояние •  Всегда возвращает один результат –  В отличие от события где данные – поток –  Не зависит от времени опроса •  Можно передавать как аргумент •  Можно выполнять операции –  then
  • 23. 23 Deferred •  Это защищенный Promise •  Разграничивает слушателя и Promise •  Слушатель не может вмешаться –  С чистыми промисами можно завершить промис на слушателе –  Меньше логических ошибок http://api.jquery.com/category/deferred-object/
  • 24. 24 Общая схема Deferred function Deferred () { this._promise = { then: function (fulfilled, rejected, progressed) {} }; } Deferred.prototype = { promise: function (error) { return this._promise; }, reject: function (error) {}, resolve: function (data) {} };
  • 25. 25 Типичный пример – обертка над XMLHttpRequest Deferred function defferedXHR(method, url, data) { var xhr = new XMLHttpRequest(), deferred = new Deffered(); xhr.open(method, url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { deferred.resolve(xhr.responseText); } else { deferred.reject(‘Error ’ + xhr.status); } } } xhr.send(data); return deferred.promise(); }
  • 26. 26 Сам код Deferred defferedXHR('GET', ‘http://host1/page.json’) .then(function (data) { data = processData(data); var promises = [ defferedXHR(‘POST’, ‘http://host2/result/’, data), defferedXHR(‘POST’, ‘http://host3/result/’, data) ]; when(promises, function (data) { alert(‘Done!’); }); }) .reject(‘Mua-ha-ha!’); // Это сделать нельзя
  • 28. 28 Streamline – попытка избавится от асинхронного шума Используют callback(err, data) Streamline var data = asyncXHR('GET', '/', null, _); asyncXHR('POST', '/', data, _); asyncXHR('POST', '/', data, _); alert('Done!'); https://github.com/Sage/streamlinejs
  • 29. 29 Happy Debug! Streamline – результат генерации (function main(_) { var data; var __frame = { name: "main”, line: 1 }; return __func(_, this, arguments, main, 0, __frame, function __$main() { return asyncXHR("GET", "/", null, __cb(_, __frame, 17, 11, function ___(__0, __1) { data = __1; return asyncXHR("POST", "/", data, __cb(_, __frame, 18, 0, function __$main() { return asyncXHR("POST", "/", data, __cb(_, __frame, 19, 0, function __$main() { alert("Done!"); _(); }, true)); }, true)); }, true)); }); }).call(this, __trap);
  • 30. 30 Streamlinejs •  Генерация кода – результат ужасен! •  Шум из массы _ •  Его цель – выполнять асинхронный код последовательно
  • 31. 31 Fibers – попытка избавится от асинхронного шума Используют callback(err, data) Fibers var Future = require('fibers/future'), wait = Future.wait; var asyncXHR = Future.wrap(asyncXHR); Fiber(function () { var data = asyncXHR(‘GET’, '...’, null).wait(); data = processData(data); asyncXHR(‘POST’, '...’, data).wait(); asyncXHR(‘POST’, '...’, data).wait(); alert(‘Done!’); }).run(); https://github.com/laverdet/node-fibers https://github.com/0ctave/node-sync
  • 32. 32 Fibers •  Особая версия Node.js –  Хак механизма yield() •  Похожи на треды –  Не могут прерываться где угодно процессором –  Меньше расходов на «безопасные зоны» •  Похожи на Event Loop –  yield() и ручное прерывание фибера –  Блокировка остальных фиберов –  Нет реального параллелизма (не занимают все ядра процессора) •  Параллельные запросы последовательно –  Необходимо использовать дополнительные функции
  • 33. 33 Позволяет выполнять асинхронный код в синхронном стиле Работает с callback(err, data) Step Step( function () { asyncXHR('GET’, ‘...’, null, this); }, function (err, data) { return processData(data); }, function (err, data) { asyncXHR(‘POST’, ‘...’, data, this.parallel()); asyncXHR(‘POST’, ‘...’, data, this.parallel()); }, function (err, result1, result2) { alert(‘Done!’); } ); https://github.com/creationix/step
  • 34. 34 Работает с Promise Представляет интерфейс для работы с промисами Q var data = promiseXHR('GET', '...'); data.than(processAndSendData).than(function () { alert(‘Done!’); }); function processAndSendData(data) { data = processData(data); return sendData(data); } function sendData(data) { return Q.all([ promiseXHR(‘POST’, ‘...’, data), promiseXHR(‘POST’, ‘...’, data) ]); } https://github.com/kriskowal/q
  • 35. 35 Асинхронность •  Событийный ввод-вывод •  Работа с GUI •  Паттерны –  Callback –  EventEmitter –  Promise –  Deferred •  Хаки –  Streamline –  Fibers •  Библиотеки –  Step –  Q