Your SlideShare is downloading. ×
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»

1,324

Published on

Асинхронность в JavaScript-приложениях – обычное дело. Любой обмен данными – асинхронный, что HTTP, что чтение файла, что БД. Все просто, если запрос один – callback, и все дела. Если логика сложнее, …

Асинхронность в JavaScript-приложениях – обычное дело. Любой обмен данными – асинхронный, что HTTP, что чтение файла, что БД. Все просто, если запрос один – callback, и все дела. Если логика сложнее, то приложение в худшем случае превращается в «Callback Pyramid of Doom» или обрастает разной магией. Promise – это подход, который выпрямляет вложенные запросы, превращает «асинхронную лапшу» в структурированный код и делает ваше приложение лучше. Вы всё еще боитесь использовать Promise? Тогда приходите на мой доклад.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,324
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Promise — это не больно! Михаил Давыдов, JavaScript-разработчик 2013 год, FrontTalks
  • 2. Асинхронность везде!
  • 3. Запросы к серверу 04
  • 4. Данные пользователя 05
  • 5. События интерфейса GARMOSHKA 06 ∞
  • 6. Таймеры и анимация 07
  • 7. Когда один callback — всё здорово!
  • 8. Последовательные запросы login('user:pass@server', function (err, server) { if (err) return cb(err); server.open('db', function (err, db) { if (err) return cb(err); db.query(query, function (err, view) {}); }); }); 01. 02. 03. 04. 05. 06. 07. 10
  • 9. Параллельные запросы var rows = [], total = view.length; function fetch(err, row) { if (err) return cb(err); if (rows.length === total) cb(null, rows); } for (var i = 0; i < total; i++) { view.get(i, fetch); } 01. 02. 03. 04. 05. 06. 07. 08. 11
  • 10. Шум login('user:pass@server', function (err, server) { if (err) return cb(err); server.open('db', function (err, db) { if (err) return cb(err); db.query(query, function (err, view) {}); }); }); 01. 02. 03. 04. 05. 06. 07. 12
  • 11. Шум ● Статус ошибки ● Однообразная обработка ошибки ● Глубина вложенности 13
  • 12. Сложно отменить действие 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
  • 13. Несколько обработчиков query(query1, function (err, view) {}); query(query2, function (err, view) {}); query(query3, function (err, view) {}); 3 запроса — 3 попытки логина. Для кэша нужно еще дописать код. 01. 02. 03. 15
  • 14. Делегирование результата function uberQueryGenerator(data) { // Готовим queryFromData return query(queryFromData); } function uberQueryGenerator(data, fn) { query(queryFromData, fn); } 01. 02. 03. 04. 01. 02. 03. 16
  • 15. У callback-ов нет единого интерфейса
  • 16. Нет единого интерфейса ● Последний аргумент ● Свойство конфига или метод – success – complete – done – finish – ??? 18
  • 17. Нет единого интерфейса $('div').animate({}, function () {}); // А можно еще вот так $('div').animate({}, { complete: function () {} }); 01. 02. 03. 04. 05. 19
  • 18. Нет единого интерфейса $.ajax({ url: url success: function () {} }); $.ajax({ url: url }).done(function () {}); 01. 02. 03. 04. 05. 06. 07. 20
  • 19. Магия
  • 20. Магия ● Step.js ● Streamline.js ● Fibers ● ??? 22
  • 21. Step.js Step(function login() { login('user:pass@server', this); }, function openDatabase(err, db) { if (err) throw err; db.query(query, this); }); 01. 02. 03. 04. 05. 06. 23
  • 22. Streamline.js var db = login('user:pass@server', _); db.query(query, _); Вроде бы ничего! 01. 02. 24
  • 23. Streamline.js (fstreamline__.create(function(_) { var db = (yield fstreamline__ .invoke(null, login, ['user:pass@server', _], 1)); (yield fstreamline__.invoke(db, "query", [query, _], 1)); ;yield;}, 0).call(this, function(err) { if (err) throw err; })); 01. 02. 03. 04. 05. 06. 07. 25
  • 24. Promise ● aka Futures ● Распостранен в других языках ● Стандартизирован Promise/A+ ● Стандарт «Покрыт тестами» Promises/A+ Compliance Test Suite ● Готовые абстракции над fs, http, ... 27
  • 25. Promise login('user:pass@server') .then(function (server) { return server.open('db'); }) .then(function (db) { return db.query(query); }) 01. 02. 03. 04. 05. 06. 07. 28
  • 26. Promise .then(function (view) { return fetchRows(view); }, function handleError(err) { console.error(err); }) // ... Меньше шума, обработка ошибок в одном месте 01. 02. 03. 04. 05. 29
  • 27. Абстракция над обещанными данными ● Обещание можно сдержать, а можно не выполнять ● Состояние изменяется только 1 раз ● Результат сохраняется ● Цепочка обещаний ● Можно пообещать нескольким 30
  • 28. Реализация 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
  • 29. Реализация Promise Promise.prototype = { // @return {Promise} then: function (onFulfilled, onRejected) {}, fulfill: function (data) {}, reject: function (error) {} }; 01. 02. 03. 04. 05. 06. 32
  • 30. Использование 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
  • 31. Пример timeout timeout(1000) .then(function () { console.log('first'); return timeout(1000); }) .then(console.log.bind(console, 'second!')); 01. 02. 03. 04. 05. 06. Run 34
  • 32. Пример timeout timeout(1000) .then(randomLog) .then(console.log.bind(console, 'done!')); function randomLog() { var rnd = Math.random(); console.log(rnd); if (rnd < 0.5) return timeout(2000); } 01. 02. 03. 04. 05. 06. 07. 08. Run 35
  • 33. Promise ● Не хак и не магия ● Единый интерфейс всех промисов ● Меньше шума в коде ● Разделение логики на шаги ● ... ● PROFIT! 36
  • 34. Трюки с Promise
  • 35. Склеивание Promise // $.when - агрегатор Promise // Результат не раньше, чем через 1с $.when($.get('/'), $.get('/?'), timeout(1000)) .then(function (res) { console.log(res[0].length + res[1].length); }); 01. 02. 03. 04. 05. 06. Run 38
  • 36. Повтор Promise new Attempt(get404, repeat3Times) .then(ok, epicFail, progress); function get404() { return $.get('/404'); } function repeat3Times(err, num) { if (num < 4) return 1000; } 01. 02. 03. 04. 05. 06. 07. 08. Run 39
  • 37. Прозрачный кэш с Promise var cache; function request() { return cache ? cache : cache = $.get('/'); } request().then(function (html) { console.log(html.length); }); 01. 02. 03. 04. 05. 06. 07. Run 40
  • 38. Promise уже рядом! ● Браузер – $.Deferred – $.when, $.ajax, $.get, $.post, ... ● Node.js – Q: q-io – Vow: vow-fs, vow-asker ● DOM Promises! WHATWG Promise Spec 41
  • 39. Generators ● Решение проблем асинхронности будущего ● Оператор yield «Ставит выполнение кода на паузу» ● Когда? – Node.js 0.11.x c --harmony-generators – Браузеры на V8 3.19 c --harmony-generators – Firefox 2+ (старый синтаксис) ● Можно транслировать в ES5, но лучше это не делать... 43
  • 40. 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
  • 41. yield vs then?
  • 42. Generators и Promise ● Именно «и», а не «VS» ● Используем вместе – Библиотека Q – Библиотека co ● С Generators код еще чище! ● Обработка ошибок с try/catch! 46
  • 43. Используйте Promise! ● Готов к использованию сегодня! ● Единый интерфейс ● Стандарт Promise/A+ ● Структурирует код ● Меньше шума в коде ● Куча библиотек: Vow, Q, jQuery 47
  • 44. Promise — это не больно! Михаил Давыдов JavaScript-разработчик @azproduction 50
  • 45. Почитать ● Примеры с презентации ● 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
  • 46. clck.ru/8i9pr

×