111
Как перестать отлаживать асинхронный код и начать жить Андрей Саломатин FrontendConf, Москва 21.05.2015

Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

  • Upload
    ontico

  • View
    796

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Как перестать отлаживать асинхронный код и начать жить

Андрей Саломатин FrontendConf, Москва

21.05.2015

Page 2: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script

Page 3: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script

function f1*red(a, b) {…}

f1*red(a, b)

function f2*blue(c) {…}

f2*blue(c)

3

Функции имеют цвет

Page 4: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script

/* OK! */

function outer*blue() {

inner*blue()

}

4

Синие могут вызывать только другие синие функции

/* NOT OK! */

function outer*blue() {

inner*red()

}

Page 5: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script

/* OK! */

function outer*red() {

inner2*red()

}

5

Красные могут вызывать и красные и синие функции

/* OK! */

function outer*red() {

inner2*blue()

}

Page 6: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Писать и вызывать красные функции больно!

6

Page 7: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script7

Красные функции нужно называть на немецком!

/* Интерпретатор не поймёт */

function authUser*red() {…}

function getName*red() {…}

Page 8: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script8

Красные функции нужно называть на немецком!

/* RICHTIG! */

function benutzerAutorisierung!*rot() {…}

function nameErhalten!*rot() {…}

Page 9: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Как писать на Schlecht!Script?

9

Page 10: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

JavaScript

Page 11: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

JavaScript extends

Schlecht!Script

11

Page 12: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Асинхронные функции это боль

12

Page 13: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

JavaScript

• По-другому работают if/else, for, return • Нет try/catch • Ломают абстракцию

13

Асинхронные функции это боль

Page 14: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

// выполнять последовательно

for (var i = 0; i < 10; i++) {

if (shouldProcess(i)) {

results.push(process(i));

}

}

14

JavaScript

if/for синхронно

Page 15: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

function maybeProcess(i) {

if (i >= 10) { return; }

shouldProcess(function(should) {

if (should) {

process(i, function(result) {

results.push(result);

maybeProcess(i++);

});

}

maybeProcess(i++);

});

}

maybeProcess(0);

15

JavaScript

if/for асинхронно

Page 16: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

JavaScript

• Не работают if/then, for и т.д. • Нет try/catch • Ломают абстракцию

16

Асинхронные функции это боль

Page 17: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Асинхронностьв JavaScript

17

Page 18: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Андрей Саломатин

Productive Mobile MoscowJS RadioJS

18

@filipovskii

Page 19: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Асинхронность

Page 20: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Множество событий

Единичная операция

20

Асинхронность: два сценария

Page 21: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)
Page 22: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Контроль

22

Page 23: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Исключения

23

Page 24: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Единый интерфейс

24

Page 25: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

25

КонтрольИсключения

Единый интерфейс

Page 26: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)
Page 27: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

• Работа с множеством событийEventEmitterStream

• Работа с асинхронными операциямиContinuation Passing Style PromisesCoroutines

27

ES6

Page 28: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

• Работа с множеством событийAsync Generators

• Работа с асинхронными операциямиAsync/Await

28

ES7

Page 29: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

ES6

Page 30: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с множеством асинхронных

событий

30

Page 31: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

31

Работа с множеством асинхронных событий

EventEmitter

Stream

Page 32: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

EventEmitter32

Объект — источник событий

Page 33: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

EventEmitter33

Примеры

Browser: XMLHttpRequest

Node: http.Server

Page 34: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

EventEmitter

emitter.addEventListener(eventName, cb);

emitter.removeEventListener(eventName, cb);

34

API

Page 35: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

EventEmitter35

События XMLHttpRequest

progress (n) load (1) abort (1) error (1)

Page 36: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

EventEmitter36

Реализации

Браузер + Node:EventEmitter3, Tiny Emitter

Node:Node EventEmitter

Page 37: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

37

Работа с множеством асинхронных событий

EventEmitter

Stream

Page 38: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

38

EventEmitter

Stream

Работа с множеством асинхронных событий

Page 39: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Поток данных

Stream39

Page 40: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Stream40

Примеры

Node: fs.createReadStream(path)

Node: gulp.src(pattern)

Page 41: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Stream41

Типы потоков

stylus files css files css prefixed files

gulp.src('*.styl') stylus() autoprefixer() gulp.dest('dist')

Page 42: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Stream42

источник преобразование преобразование потребитель

gulp.src('*.styl') stylus() autoprefixer() gulp.dest('dist')

Типы потоков

Page 43: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

43

Page 44: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Stream44

Реализации

Изоморфные: RxJS, Kefir, Bacon.js

Node:Node Streams

Page 45: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

45

Работа с множеством

EventEmitter Stream

Page 46: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

46

Контроль

Исключения

Единый интерфейс

EventEmitter, Stream

Page 47: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями

47

Page 48: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

48

Работа с асинхронными операциями

Continuation Passing Style Promises

Coroutines

Page 49: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Continuation Passing Style49

Примеры

Browser:

navigator.geolocation.getCurrentPosition(cb)

Node:

fs.stat(path, cb)

Page 50: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

try {

var user = fetchUser(userId);

var following = fetchFollowingUsers(userId);

var tweets = fetchTweets(following);

handleResult(tweets);

} catch (err) {

handleError(err);

}

50

Continuation Passing Style

Получить ленту твитов синхронно Получить ленту твитов асинхронно

Page 51: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

fetchUser(userId, function(err, user) {

if (err) { return handleError(err); }

fetchFollowingUsers(user, function(err, following) {

if (err) { return handleError(err); }

fetchTweets(following, function(err, tweets) {

if (err) { return handleError(err); }

handleResult(tweets);

});

});

});

51

Continuation Passing Style

Получить ленту твитов асинхронно

Page 52: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

fetchUser(userId, function(err, user) {

if (err) { return handleError(err); }

fetchFollowingUsers(user, function(err, following) {

if (err) { return handleError(err); }

fetchTweets(following, function(err, tweets) {

if (err) { return handleError(err); }

52

Continuation Passing Style

Получить ленту твитов асинхронно

Page 53: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

holenBenutzer!*rot(userId, function(err, user) {

if (err) { return handleError*blue(err); }

holenFolgendenBenutzer!*rot(user, function(err, following) {

if (err) { return handleError*blue(err); }

holenTweets!*rot(following, function(err, tweets) {

if (err) { return handleError(err); }

53

Continuation Passing Style

Holen Sie sich die Band tweets asynchron!

Page 54: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

54Schlecht!Script

Page 55: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

55

Работа с асинхронными операциями

Continuation Passing Style

Promises

Coroutines

Page 56: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

56

Continuation Passing Style

Promises

Coroutines

Работа с асинхронными операциями

Page 57: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Объект — асинхронная операция

Promises57

Page 58: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Promise.prototype.then(successCb, errorCb);

58

API

Promises

Page 59: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

fetchUser(userId)

.then(fetchFollowingUsers)

.then(fetchTweets)

.then(handleResult, handleError);

59

Promises

API

Page 60: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Promises vs

Continuation Passing Style

60

Page 61: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

61

Реализации

jQuery.Deffered Bluebird RSVP Q

Promises

Page 62: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

62

Continuation Passing Style

Promises

Coroutines

Работа с асинхронными операциями

Page 63: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

63

Continuation Passing Style

Promises

Coroutines

Работа с асинхронными операциями

Page 64: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Coroutines64

Page 65: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Coroutines

function getUserName(userId) {

var user = getUser(userId);

return user.name;

}

65

Остановите землю!

Page 66: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Функция, которую можно приостановить и возобновить

позже

66

Coroutines

Page 67: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

function * getUserName (userId) {

var user = yield getUser(userId);

return user.name;

};

67

Генераторы: шаг 1 из 3

Coroutines

Page 68: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

function * getUserName (userId) {

var user = yield getUser(userId);

return user.name;

};

68

Coroutines

Генераторы: шаг 1 из 3

Page 69: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

getUserName = co.wrap(function * (userId) {

var user = yield getUser(userId);

return user.name;

});

69

Coroutines

Генераторы: шаг 2 из 3

Page 70: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

getUserName = co.wrap(function * (userId) {

var user = yield getUser(userId);

return user.name;

});

70

Coroutines

Генераторы: шаг 2 из 3

Page 71: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

userNamePromise = getUserName(userId);

71

Coroutines

Генераторы: шаг 3 из 3

Page 72: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Использовать генераторы для асинхронного кода —

это хак

72

Page 73: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Использовать генераторы для асинхронного кода —

это хак

73

(но я вас не выдам)

Page 74: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

74

Реализации

Браузер + Node (используют транспайлер):co (generators), task.js (generators)

Node (использует транспайлер):Fibers

Coroutines

Page 75: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

75

Continuation Passing Style

Promises

Coroutines

Работа с асинхронными операциями

Page 76: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

76

Контроль

Исключения

Единый интерфейс

CPS, Promises, Coroutines

Page 77: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с множеством событий: EventEmitter Stream

Работа с асинхронными операциями: CPS Promise Coroutine

77

ES6

Page 78: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)
Page 79: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

ES7

Page 80: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями: Async/Await

Работа с множеством событий: Async Generators

80

ES7

Page 81: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями: Async/Await

Работа с множеством событий: Async Generators

81

ES7ES7

Page 82: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Async/Await

getUserName = co.wrap(function * (userId) {

var user = yield getUser(userId);

return user.name;

});

82

Генераторы

Page 83: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function getUserName(userId) {

var user = await getUser(userId);

return user.name;

}

83

Async/Await

Async/Await

Page 84: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function getUserName(userId) {

var user = await getUser(userId);

return user.name;

}

84

Асинхронная функция

Async/Await

Page 85: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Асинхронные функции легализованы в ES7

85

Async/Await

Page 86: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями: Async/Await

Работа с множеством событий: Async Generators

86

ES7

Page 87: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями: Async/Await

Работа с множеством событий: Async Generators

87

ES7

Page 88: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Подписка на события для людей

Async Generators88

Page 89: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function doDraw() {

for (let ev on observe(win, 'mousemove')) {

draw(ev.clientX, ev.clientY);

}

}

89

События DOM

Async Generators

Page 90: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function doDraw() {

for (let ev on observe(win, 'mousemove')) {

draw(ev.clientX, ev.clientY);

}

}

90

Async Generators

События DOM

Page 91: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

doDrawPromise = doDraw();

91

Async Generators

События DOM

Page 92: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function *filterWSMessages(ws) {

for (let msg on observe(ws, 'message')) {

if (isValid(msg)) yield msg;

}

}

92

WebSocket сообщения

Async Generators

Page 93: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

async function *filterWSMessages(ws) {

for (let msg on observe(ws, 'message')) {

if (isValid(msg)) yield msg;

}

}

93

WebSocket сообщения

Async Generators

Page 94: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

??? = filterWSMessages(ws);

??? = observe(win, 'mousemove');

??? = observe(ws, 'message');

94

Что возвращает Async Generator?

Async Generators

Page 95: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

messagesObservable = filterWSMessages(ws);

eventsObservable = observe(win, 'mousemove');

eventsObservable = observe(ws, 'message');

95

Async Generators

Что возвращает Async Generator?

Page 96: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Observables

Streamsaka

Page 97: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Работа с асинхронными операциями: Async/Await

Работа с множеством событий: Async Generators

97

ES7

Page 98: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

ES6 и ES7: асинхронные операции

98

Page 99: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

fetchUser(userId, function(err, user) {

if (err) { return handleError(err); }

fetchFollowingUsers(user, function(err, following) {

if (err) { return handleError(err); }

fetchTweets(following, function(err, tweets) {

if (err) { return handleError(err); }

handleResult(tweets);

});

});

});

99

ES6 и ES7

Получить ленту твитов: CPS

Page 100: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

fetchUser(userId)

.then(fetchFollowingUsers)

.then(fetchTweets)

.then(handleResult, handleError);

100

Получить ленту твитов: Promise

ES6 и ES7

Page 101: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

try {

var user = await fetchUser(userId);

var following = await fetchFollowingUsers(userId);

var tweets = await fetchTweets(following);

handleResult(tweets);

} catch (err) {

handleError(err);

}

101

Получить ленту твитов: Async/Await

ES6 и ES7

Page 102: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

ES6 и ES7: обработка множества событий

102

Page 103: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

var handler = function(ev) {

if (canDraw(ev)) {

draw(ev.clientX, ev.clientY);

}

};

window.addEventListener('mousemove', handler);

window.removeEventListener('mousemove', handler); // позже

103

DOM события: EventEmitter

ES6 и ES7

Page 104: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Kefir.fromEvent(window, 'mousemove')

.filter(canDraw)

.onValue(function(ev) {

draw(ev.clientX, ev.clientY)

})

.end(); // позже

104

DOM события: Stream

ES6 и ES7

Page 105: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

for (ev on observe(window, 'mousemove')) {

if (canDraw(ev)) {

draw(ev.clientX, ev.clientY);

}

}

105

DOM события: Async Generators

ES6 и ES7

Page 106: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Как перестать отлаживать асинхронный

код и начать жить

106

Page 107: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Определите задачу

107

Page 108: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Обдумайте ограничения

108

Page 109: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Используйте лучшие практики

109

Page 110: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Schlecht!Script?

Page 111: Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Productive Mobile)

Спасибо!

bit.ly/async-js

Андрей Саломатин @filipovskii

FrontendConf, Москва 21.05.2015