CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

44
Промисы и jQuery Промисы
  • date post

    20-Oct-2014
  • Category

    Internet

  • view

    1.171
  • download

    1

description

 

Transcript of CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Page 1: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Промисы и jQueryПромисы

Page 2: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Олег Гайдаренко / markelog

Page 3: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Concurrency

Page 4: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Способыпараллельного

исполнения задачТредыПроцессыFibersCoroutineetcиPromise'ы

Page 5: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

JS is a single­threadlanguage

Браузеры имеют только одинтредтак же как и NodeJS

Page 6: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Но при этомВ NodeJS

Worker'ыЧтение/запись сдискаСетевые запросыetc

БраузерыСетевые запросыДекодирование изображенияНекоторые из CSS-transition'овWeb-worker'ыetc

Page 7: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

История промисовПридуманы в 1976 годуПервая «имплементация» в MultiLisp'е в 1980-ыхОкончательное сформирование концепции в 1988годуПервая имлементация в E в 1997 году

Page 8: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

В ДжаваскриптеСначала в MochaKit – 2005 год

Реализация вдохновлена фреймворком Twister (Python)Dojo – 2006 год

CommonJS предложение – 2010 годИдея популязирована с имплементацией в jQuery c версии 1.5 –

2011 год

Page 9: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Предложения вCommonJS

Page 10: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Promises/AОписана только основная концепция – пайпинг, неизмеямостьстейта, поведение при появлении ошибки и метод «then»Есть так же еще несколько «спек» – B, KISS, DОснованные на той или иной библиотеки для промисовНо все они остались в тени Promise/A предложения

Page 11: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Domenic Denicola

Page 12: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Его участие в истории промисов началось с библиотеки как расширение для библиотеки юнит-тестов

Первое в эту библиотеку, описывала проблему работы вместес jQuery промисамиВпоследствии эта продолжилась в jQuery баг-трекереВ ней обсуждались одна деталь имплементации промисов в jQuery,которая казалось бы не была такой уж важной

chai-as-promised Chai

issue

дискуссия

Page 13: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Сначала никто неслушал

"Your point go from very helpful to laughablyinsane""That's complete non-sense""We do not want to do that"

Page 14: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Но со временем...Доменик становился все более и более вокальнымЕго участие начало проявляться во многих популярных промис-библиотекВроде и И вот год назад поступил в клиентскую MVC-библиотеку Этот пулл имплементировал jQuery-like промисы в Ядро ЭмбераЧто было неприемлимо с точки зрения Доменика, это сподвигло егонаписать известную и во многом поворотную в историиприображения концепции ПромисовПлодом которой является спека

Q when.jsпулл-реквест

Эмбер

статью

Promise/A+

Page 15: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Promise/A+На ней основываются большинство существующих промис-имплементацийОписывает более детальный и ясный процесс резолвинга промисаи работу метода thenГарантированное ассинхронное исполнение и самое важное...

Page 16: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

InteroperableОзначает совместимость между любой библиотекойреализовывающих спекуЭто достигается точностью и четкостью формулировокспецификации:

Promise/A библиотеки могли бы быть всегда ассинхронными илииногда ассинхроннымиthen-метод мог иметь progressHandler, а могли и не иметьetc

Page 17: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

В NodeJSNodeJS становилась все более и более популярнойТак же как и ассинхронная модель работы с ней становилась всеболее и более раздражающейПромисы же являются элигантным решением выхода из...

Page 18: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Callback Hellfirst(function () { second(function () { third(function () { fourth(function () { iDontKnowHowMuchMoreOfThisICanTake(function () { // Fuck this, i'm going home }); }); }); });});

Page 19: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

А с промисамиfirst().then( second ).then( third ).then( fourth ).yeahhh(function() { // Now we talking});

Page 20: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

$.when( first, second, third, fourth, loveIt ).then(function() { // This is how we do!});

Page 21: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

DOM PromisesСо временем возникло понимание необходимости решения этойпроблемы на уровне языкаЭто нужно было решать и нужно было решать быстроTC39-коммитет довольно медленно и обстоятельно включаетновые идеи в языкПоэтому для того что бы ускорить этот процесс, стандартизацияПромисов на уровне ДОМ'аПосле некоторых метафорфоз эта спека стала являлаться простой

на репозиторий Доменика

началась

ссылкой

Page 22: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

APIКак Promise/A+ расширяет Promise/A, так и DOM Promise'ырасширяют Promise/A+i.e. DOM Promise спека является совместимой с Promise/A+Предыдущие спеки не задавали то как должен быть созданПромис-объектПомимо метода then, спека декларирует достаточное API дляработы с ассинхронными задачамиНо при этом предоставляет минималистичное АПИ, последующиерасширения же должны происходить на уровне библиотек

Page 23: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

ВендорыЭтого черновика уже было достаточно для разработчиковДжаваскрипт движковВ SpiderMonkey и V8 они включены как примитивы языкаБраузеры же всего лишь эмитируют промисы как ДОМ API, хотятаким он не являлсяПри этом в Chromium'е, не смотря на то что эта спецификацияявляется драфтом, промисы уже включены по-умолчаниюТакая поспешность порадила довольно много ошибок вимплементации

Page 24: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

ECMAScript 6Но Промисы должны быть имлементированы на уровне языка!После того как в спеку были внесены дополнительные правки, 20-ого Января 2014 года, новая спецификация была внесена в драфтECMAScript 6Но для того чтобы описание Промисов было достаточно дляимплементации на уровне движка, в язык пришлось внести понятиеTask'ов

Page 25: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Microtasks vs Macrotasks

Page 26: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Синхронные иАссинхронные I/O

Например:fs.readFileSync() и fs.readFile()$.ajax({ async: false }) и $.ajax()

Page 27: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
Page 28: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Microtasks queueprocess.nextTick, Object.observe

Page 29: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Macrotasks queueОни же:

«Task Queue» в HTML5Или «Event Queue» вДарте

setTimeout, setIntervalI/OsetImmediate – особый метод, так же работает с очередьюмакротасков, но кладет их на самый верх FIFO стека

Page 30: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

А что же jQueryDeferred?

Page 31: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Критика"Promise implementation in jQuery is broken""But just like I should be nice to retarded children, I probably should alsowelcome jQuery promises" @domenicИ довольно большое количество людей в той или иной степенипереиначивающих слова ДоменикаjQuery по-прежнему нарушает все существующие Промис спекиИ будет их нарушать!

Page 32: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

TC39jQuery Foundation состоит в TC39И могли бы заблокировать новую ECMAScript ПромисспекуНо мы не хотим быть злодеями в этой истории

Page 33: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Так чем же jQuery имплиментациявызвала такую ненависть?

Ровно четырьмя аспектами

Page 34: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

У then метод естьprogressHandler callback

progressHandler опционален в Promise/A, но исключен изPromise/A+

Page 35: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Плюсы/минусыПромис теперь не может иметь транзитивныйстейтНу и ладно, зато АПИ более строг и фокусирован

Page 36: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Успешные/Неудавшиеся Каллбекимогут иметь любое количество

аргументовvar def = $.Deferred();def.promise().then(function() { console.log( arguments.length ); // 7});

def.resolve( 0, 1, 2, 3, 4, 5, 6 );

vsvar def = when.defer();def.promise.then(function() { console.log( arguments.length ); // 1});def.resolve( 0, 1, 2, 3, 4, 5, 6 );

Page 37: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Плюсы/минусыСубъективно это менее удобноЕсли нужно передать несколько аргументов, придется хачить ипередавать один объект с нужными свойствамиНу и ладно, зато промис объект теперь представляет собойрезультат выполнение задачиТак же это более консистентно с try...catch конструкцией

Page 38: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Не гарантирует асинхронноеисполнение

Еще одно Promise/A+ нововведениеvar def = $.Deferred();def.promise().then(function() { console.log( 1 );});

def.resolve();console.log( 2 );// 1 2

vsvar def = vow.defer();def.promise().then(function() { console.log( 1 );});

def.resolve();console.log( 2 );// 2 1

Page 39: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Плюсы/минусыМедленее, намного медленееНо зато гарантия асинхронного выполнения помогает создаватьдетерминированную логику, без опасения что какой-то каллбеквыполнится раньше чем должен был бы

Page 40: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

ОптимизацияГодная оптимизация из Vow.js

first().then( second ).then( third ).then( fourth )

Page 41: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Не проглатывает ошибкиvar def = $.Deferred();def.promise().then(function() { throw "Error"}).fail(function( error ) { // Will not be called, // instead error will propagate to the main flow console.log( error );});

vsvar def = Q.defer();def.promise.then(function() { throw "Error";}).catch(function( error ) { console.log( error ); // "Error"});

Page 42: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Плюсы/минусыЕсли отсутствует errorHandler, ошибка никогда не будетпоказана пользователюНо такая парадигма дает возможность всплывать ошибкам поцепочки промисовТогда как в jQuery (если нет try...catch клаузы внутри thenметода) ошибка будет отправлена в основной потокНо эта проблема более релевантна при дебаге, чем для продакта

Page 43: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

Что мы собираемсяс этим делать?

Мы не можем изменить сигнатуру then метода, а так жеколичество аргументов в каллбеках, и все из-за обратнойсовместимостиМы скорее всего будем гарантировать асинхронное выполнениекаллбековМы подняли вопрос о возможности проглатывания ошибок в случаеотсутствия каллбека для неудачной резолва

Page 44: CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы

The End