Асинхронность в JavaScript-приложениях – обычное дело. Любой обмен данными – асинхронный, что HTTP, что чтение файла, что БД. Все просто, если запрос один – callback, и все дела. Если логика сложнее, то приложение в худшем случае превращается в «Callback Pyramid of Doom» или обрастает разной магией. Promise – это подход, который выпрямляет вложенные запросы, превращает «асинхронную лапшу» в структурированный код и делает ваше приложение лучше. Вы всё еще боитесь использовать Promise? Тогда приходите на мой доклад.
14. Сложно отменить действие
db.query(query, function (err, view) {});
Как отменить или игнорировать запрос в этом случае?
db.query(query, fn).abort(); // .cancel() ?
db.query(query, function (err) {
if (err.message === 'abort') return;
});
01.
01.
02.
03.
04.
14
15. Несколько обработчиков
query(query1, function (err, view) {});
query(query2, function (err, view) {});
query(query3, function (err, view) {});
3 запроса — 3 попытки логина. Для кэша нужно еще дописать код.
01.
02.
03.
15
27. Promise
● aka Futures
● Распостранен в других языках
● Стандартизирован Promise/A+
● Стандарт «Покрыт тестами» Promises/A+ Compliance Test Suite
● Готовые абстракции над fs, http, ...
27
29. Promise
.then(function (view) {
return fetchRows(view);
}, function handleError(err) {
console.error(err);
}) // ...
Меньше шума, обработка ошибок в одном месте
01.
02.
03.
04.
05.
29
30. Абстракция над обещанными
данными
● Обещание можно сдержать, а можно не выполнять
● Состояние изменяется только 1 раз
● Результат сохраняется
● Цепочка обещаний
● Можно пообещать нескольким
30
31. Реализация Promise
var Promise = function () {
this._value = null;
this.isFulfilled = false; // ok
this.isRejected = false; // fail
this.isResolved = false; // ok || fail
// ...
};
01.
02.
03.
04.
05.
06.
07.
31
32. Реализация Promise
Promise.prototype = {
// @return {Promise}
then: function (onFulfilled, onRejected) {},
fulfill: function (data) {},
reject: function (error) {}
};
01.
02.
03.
04.
05.
06.
32
33. Использование Promise
// @param {Number} time
// @return {Promise}
function timeout(time) {
var promise = new Promise();
setTimeout(promise.fulfill, time);
return promise;
}
01.
02.
03.
04.
05.
06.
07.
33
43. Generators
● Решение проблем асинхронности будущего
● Оператор yield «Ставит выполнение кода на паузу»
● Когда?
– Node.js 0.11.x c --harmony-generators
– Браузеры на V8 3.19 c --harmony-generators
– Firefox 2+ (старый синтаксис)
● Можно транслировать в ES5, но лучше это не делать...
43
44. Generators
var co = require('co');
co(function *() {
var server = yield login('user:pass@server'),
db = yield server.open('db'),
view = yield db.query(query);
});
Скоро на экранах ваших IDE
01.
02.
03.
04.
05.
06.
44
46. Generators и Promise
● Именно «и», а не «VS»
● Используем вместе
– Библиотека Q
– Библиотека co
● С Generators код еще чище!
● Обработка ошибок с try/catch!
46
47. Используйте Promise!
● Готов к использованию сегодня!
● Единый интерфейс
● Стандарт Promise/A+
● Структурирует код
● Меньше шума в коде
● Куча библиотек: Vow, Q, jQuery
47
48.
49.
50. Promise — это не больно!
Михаил Давыдов
JavaScript-разработчик
@azproduction
50
51. Почитать
● Примеры с презентации
● Promises/A+
● Differences from Promises/A
● Design of Q library (настоятельно рекомендую)
● Iterators & Generators
● A Study on Solving Callbacks with JavaScript Generators
● A Closer Look at Generators Without Promises
51