SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Downloaden Sie, um offline zu lesen
Михаил Давыдов
Разработчик 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
Спасибо

Weitere ähnliche Inhalte

Was ist angesagt?

Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Vasya Petrov
 
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_samsonovComputer Science Club
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
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 GammaEvgeniy Kuzmin
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORMBadoo Development
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...Ontico
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...Alexey Paznikov
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...solit
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NETPositive Hack Days
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2Technopark
 
Подводные камни System.Security.Cryptography
Подводные камни System.Security.CryptographyПодводные камни System.Security.Cryptography
Подводные камни System.Security.CryptographyVladimir Kochetkov
 
Подводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IПодводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IVladimir Kochetkov
 
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Отладка и устранение проблем в PostgreSQL Streaming Replication.
Отладка и устранение проблем в PostgreSQL Streaming Replication.Alexey Lesovsky
 

Was ist angesagt? (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
 

Ähnlich wie JavaScript. Async (in Russian)

Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxYandex
 
Mihail davidov js-ajax
Mihail davidov js-ajaxMihail davidov js-ajax
Mihail davidov js-ajaxYandex
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Vasya Petrov
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptSmartTools
 
Web весна 2013 лекция 9
Web весна 2013 лекция 9Web весна 2013 лекция 9
Web весна 2013 лекция 9Technopark
 
Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Alex Tumanoff
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)Noveo
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Googleyaevents
 
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 coroutinescorehard_by
 
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Timur Shemsedinov
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4Technopark
 
Web весна 2012 лекция 9
Web весна 2012 лекция 9Web весна 2012 лекция 9
Web весна 2012 лекция 9Technopark
 
FPUG Dzyga presentation
FPUG Dzyga presentationFPUG Dzyga presentation
FPUG Dzyga presentationIvan Filimonov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 

Ähnlich wie 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
 

Mehr von Mikhail Davydov

Components now! (in russian)
Components now! (in russian)Components now! (in russian)
Components now! (in russian)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 RussianMikhail Davydov
 
Dump-IT Загрузка и инициализация JavaScript
Dump-IT Загрузка и инициализация JavaScriptDump-IT Загрузка и инициализация JavaScript
Dump-IT Загрузка и инициализация JavaScriptMikhail Davydov
 
Dart - светлая сторона силы?
Dart - светлая сторона силы?Dart - светлая сторона силы?
Dart - светлая сторона силы?Mikhail Davydov
 
Making Scalable JavaScript Application
Making Scalable JavaScript ApplicationMaking Scalable JavaScript Application
Making Scalable JavaScript ApplicationMikhail Davydov
 

Mehr von 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