Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reactive programming with RxJS - Taiwan

65 views

Published on

Learn what reactive programming is and how to use it with RxJS in this talk done in Taiwan 2018.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Reactive programming with RxJS - Taiwan

  1. 1. @ladyleet 💜
  2. 2. Tracy Lee See you in 2019! https://2018.angular.tw/ @ladyleet
  3. 3. The Magic of Reactive Programming: With RxJS Tracy Lee Taiwan 2018 @ladyleet
  4. 4. @ladyleet Reactive Programming
  5. 5. @ladyleet How many of you practice Reactive Programming?
  6. 6. @ladyleet Tracy Lee | @ladyleet Co-Founder, This Dot Labs ● Google Developer Expert ● RxJS Core Team ● Community Rel, Node.js @ Node Foundation ● JavaScript Developer - all the things ● Vue Vixens Board Member ● Google Women Techmakers Lead ● Modern Web Podcast ● Google Developer Group, Silicon Valley & Triangle
  7. 7. @ladyleet 台灣的食物 太好吃了!!!
  8. 8. @ladyleet 如果有地方我應該去吃的話就 DM me on twitter @ladyleet!
  9. 9. @ladyleet Back to important things
  10. 10. @ladyleet Reactive Programming
  11. 11. @ladyleet So what is Reactive Programming really?
  12. 12. @ladyleet Wikipedia says… Reactive programming is a programming paradigm concerned with data streams and the propagation of change.
  13. 13. @ladyleet Wikipedia says… This means that it becomes possible to express static or dynamic data streams with ease via the employed programming language
  14. 14. @ladyleet Wikipedia says… and that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the change involved with data flow.
  15. 15. @ladyleet ● Dealing with sets of events over time ● Automatic, implicit (not explicit), propagation of change ● Each step doesn't know or care about the previous step ● Each step performs an action when it reacts to the incoming change In Layman’s terms...
  16. 16. @ladyleet In Layman’s terms...
  17. 17. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  18. 18. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  19. 19. @ladyleet TC39 ● Promises ● Observables WHATWG ● EventTarget Observable Reactive programming in standards
  20. 20. @ladyleet ● Added to browsers ~2014 ● Added to Node.js ~2015 ● ECMAScript 2015 ● Push-based ● Single value ● Always async ● Eager ● Stateful ● Simple base API ● Simple transformation options (then, catch) Promises
  21. 21. Promises fetch('fruitsnacks.json') .then(resp => resp.json()) .then(fruitsnacks => console.log('I have fruit snacks!'));
  22. 22. @ladyleet ● TC39 Proposal - Stage 1 https://github.com/tc39/proposal-observable ● RxJS is a reference implementation ● Simple base API ● Push-based ● Multiple values ● Sync or async ● Generally stateless ● Lazy ● Many transformation options OOTB (via RxJS) Observable
  23. 23. Observable (RxJS) import { ajax } from ‘rxjs/ajax’; ajax.getJSON(‘fruitsnacks.json’) .subscribe(fruitsnacks => console.log(fruitsnacks));
  24. 24. @ladyleet ● WHATWG Proposal - http://github.com/whatwg/dom/issues/544 ● Add method called “on” to EventTarget ● Comes with operators (map, filter, first, TakeUntil) EventTarget Observable
  25. 25. EventTarget Observable button.on('click’);
  26. 26. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  27. 27. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  28. 28. @ladyleet Reactive Programming in Frameworks & Libraries D3 VueAngular React
  29. 29. var numbers = [15, 8, 42, 4, 32]; function update() { var selection = d3.select(“#chart”) .selectAll(“.bar”).data(numbers) .style(“height”, function(d) { return d + “px”; }) .style(“margin-top”, function(d) { return (100 - d) + “px”; }); Reactive Programming in D3 selection.enter() .append(“div”).attr(“class”, “bar”) .style(“height”, function(d) { return (100 - d) + “px”; }) .on(“click”, function(e, i) { numbers.splice(i, 1); update(); }); selection.exit().remove(); }; update();
  30. 30. @ladyleet Reactive Programming in Angular Angular & RxJS are besties
  31. 31. @ladyleet Reactive Programming in Angular NgRx
  32. 32. @ladyleet ● RxJS is a 1st class citizen ● .OnPush change detection strategy ● Angular Router ● Reactive forms Reactive Programming in Angular
  33. 33. @ladyleet Reactive Programming in React redux-observableReact MobX
  34. 34. @ladyleet Reactive Programming in React redux-observableReact MobX
  35. 35. @ladyleet Reactive Programming in React redux-observableReact MobX
  36. 36. @ladyleet Reactive Programming in React React MobXredux-observable
  37. 37. @ladyleet Reactive Programming in Vue Vue-Rx https://github.com/vuejs/vue-rx
  38. 38. @ladyleet Reactive is just a fancy term to quantify a way of programming.
  39. 39. @ladyleet Reactive Programming Patterns appear where there is a natural fit for events to be modeled as values over time. Web sockets, user events, animations, HTTP requests, network connections, file system changes, etc
  40. 40. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  41. 41. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  42. 42. @ladyleet Everything can be modeled as an event All applications are event driven Everything can be represented as a set of values over time, even events. How do you think reactively?
  43. 43. @ladyleet Everything can be represented as a set of values over time, even events.
  44. 44. @ladyleet Definition of set: a set in the math sense { a, b, c }. Current mindset: When an action happens, you get one value back. New mindset: Treat events as sets of values. Example sets: { }, { 0 }, { 1, 2, 3 } Everything can be represented as a set of values over time, even events.
  45. 45. @ladyleet If everything is a set, you can do more with your data. You can query them, map them, filter them… Join and combine them in different ways… Give something a half a set of things or things with a set of parameters. Everything can be represented as a set of values over time, even events.
  46. 46. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  47. 47. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  48. 48. @ladyleet What is RxJS? Domain specific language (DSL) for reacting to events The most popular reactive programming library
  49. 49. @ladyleet Did you know there are other dialects? RxJava, RxPhp, Rx.NET, RxRuby, RxCPP, RxSwift...
  50. 50. @ladyleet What an Observable Is The simple, technical, nutshell version
  51. 51. Imagine it's just a function function myObservable() { }
  52. 52. We call it with an observer with handlers on it function myObservable(observer) { }
  53. 53. We call next on the observer to emit values function myObservable(observer) { observer.next(1); }
  54. 54. We call error on the observer if there's a problem function myObservable(observer) { observer.next(1); if (someCondition) { observer.error(new Error('end of the world')); } }
  55. 55. We call complete on the observer if we're done emitting values function myObservable(observer) { observer.next(1); if (someCondition) { observer.error(new Error('end of the world')); } observer.complete(); }
  56. 56. To use our observable, we call it with an observer object const observer = { next(value) { console.log(value); }, error(err) { console.error(err); }, complete() { console.log('done'); }, }; myObservable(observer);
  57. 57. It could even return a teardown function to finalize const teardown = myObservable({ next(value) { console.log(value); }, error(err) { console.error(err); }, complete() { console.log('done'); }, }); teardown();
  58. 58. @ladyleet So why not just use functions?
  59. 59. We don't want those calls out of order function myObservable(observer) { observer.next(1); if (someCondition) { observer.error(new Error('end of the world')); } observer.complete(); observer.next('oops'); }
  60. 60. Was there a teardown returned or not? const teardown = myObservable({ next(value) { console.log(value); }, error(err) { console.error(err); }, complete() { console.log('done'); }, }); if (teardown) teardown();
  61. 61. What if you don't want a handler? myObservable({ next(value) { console.log(value); }, error(err) { console.error(err); }, }); complete? where are you?!
  62. 62. Tearing down on complete and error, too const teardown = myObservable({ next(value) { console.log(value); }, error(err) { console.error(err); if (teardown) teardown(); }, complete() { console.log('done'); if (teardown) teardown(); }, }); if (teardown) teardown();
  63. 63. We can just take our function... function myObservable(observer) { observer.next(1); if (someCondition) { observer.error(new Error('end of the world')); } observer.complete(); }
  64. 64. … and wrap it in a class that handles that stuff const myObservable = new Observable((observer) => { observer.next(1); if (someCondition) { observer.error(new Error('end of the world')); } observer.complete(); });
  65. 65. Instead of calling it directly... const teardown = myObservable({ next(value) { console.log(value); }, error(err) { console.error(err); if (teardown) teardown(); }, complete() { console.log('done'); if (teardown) teardown(); }, }); if (teardown) teardown();
  66. 66. ...We call it via subscribe const subscription = myObservable.subscribe({ next(value) { console.log(value); }, error(err) { console.error(err); }, complete() { console.log('done'); }, }); subscription.unsubscribe();
  67. 67. ...We call it via subscribe const subscription = myObservable.subscribe({ next(value) { console.log(value); }, error(err) { console.error(err); }, complete() { console.log('done'); }, }); subscription.unsubscribe();
  68. 68. @ladyleet Observables Are Just Functions With a lot of cool guarantees
  69. 69. @ladyleet What is an "Operator"? Just a transformation from one Observable into another
  70. 70. "operators" in Arrays const arr = [1, 2, 3, 4, 5, 6, 7]; arr.filter(x => x % 2 === 0); // [2, 4, 6] arr.map(x => x + x); // [2, 4, 6, 8, 10, 12, 14] arr.filter(x => x % 2 === 0) .map(x => x + x); // [4, 8, 12]
  71. 71. "operators" in Observables import { of as observableOf } from 'rxjs'; import { map, filter } from 'rxjs/operators'; const src = observableOf(1, 2, 3, 4, 5, 6, 7); src.pipe( filter(x => x % 2 === 0), map(x => x + x), ).subscribe(x => console.log(x)); // 4...8...12...
  72. 72. A simple map operator implementation import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  73. 73. Takes an observable and returns a new one import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  74. 74. Subscribes to the source... import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  75. 75. … and passes along the transformed value. import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  76. 76. … as well as sending along the other signals import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  77. 77. @ladyleet There are 60+ operators in RxJS (You probably won't need to implement your own often) ● map ● filter ● scan ● take ● reduce ● mergeMap ● concatMap ● switchMap ● takeUntil ● catchError
  78. 78. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  79. 79. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we’ll talk about today
  80. 80. @ladyleet With RxJS you can do cool things with less code.
  81. 81. @ladyleet Like drag and drop in Angular could be easy.
  82. 82. @ladyleet Show demo here
  83. 83. import { Component } from '@angular/core'; import { fromEvent } from 'rxjs/observable/fromEvent'; import { Subscription } from 'rxjs/Subscription'; import { filter, mergeMap, tap, takeUntil, map } from 'rxjs/operators';
  84. 84. @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; mouseDown$ = fromEvent(document, 'mousedown'); mouseMove$ = fromEvent(document, 'mousemove'); mouseUp$ = fromEvent(document, 'mouseup'); subscription: Subscription;
  85. 85. targetMouseDown$ = this.mouseDown$.pipe( filter((e: any) => e.target.matches('. ')) )
  86. 86. mouseDrag$ = this.targetMouseDown$.pipe( mergeMap(({ target: draggable, offsetX: startX, offsetY: startY }) => this.mouseMove$.pipe( tap((mouseMoveEvent: any) => { mouseMoveEvent.preventDefault() }), map((mouseMoveEvent: any) => ({ left: mouseMoveEvent.clientX - startX, top: mouseMoveEvent.clientY - startY, draggable })), takeUntil(this.mouseUp$) ) )
  87. 87. ngOnInit() { this.subscription = new Subscription(); this.subscription.add(this.mouseDrag$.subscribe(({ top, left, draggable }) => { draggable.style.top = top + 'px'; draggable.style.left = left + 'px'; })); } ngOnDestroy() { this.subscription.unsubscribe(); }
  88. 88. <div> <img class="🍩 " src="./assets/donut.png" alt="donut"> <img class="🍟 " src="./assets/fries.png" alt="fries"> <img class="🐟 " src="./assets/goldfish.png" alt="goldfish"> <img class="🍔 " src="./assets/hamburger.png" alt="hamburger"> <img class="🍕 " src="./assets/pizza.png" alt="pizza"> <img class=" " src="./assets/taco.png" alt="taco"> <img class=" " src="./assets/hotdog.png" alt="hotdog"> </div>
  89. 89. @ladyleet Show demo here
  90. 90. @ladyleet It’s cute, right?
  91. 91. @ladyleet We could do more complex things like multiplexing over a websocket using RxJS.
  92. 92. @ladyleet Multiplexing over a websocket... what? Sending and receiving multiple independent requests and responses concurrently over the same websocket.
  93. 93. @ladyleet
  94. 94. import React from ‘react’; import { StyleSheet, Text, View, Image, Button } from ‘react-native’; import { webSocket } from ‘rxjs/webSocket’; import { groupBy, mergeMap, takeUntil, finalize } from ‘rxjs/operators’; import { timer } from ‘rxjs’; import kenwheeler from ‘./ken_wheeler.png’;
  95. 95. export default class App extends React.Component { state = { randomKens: {} }; socket$ = webSocket(‘ws://localhost:8080’); requestKenHead() { const msg = JSON.stringify({ type: ‘REQUEST_KEN_HEAD’ }); this.socket$.next(msg); }
  96. 96. componentDidMount() { const kenHead$ = this.socket$.pipe { groupBy(data => data.id), mergeMap(singleKenStream => singleKenStream.pipe( takeUntil( timer(3000), ), finalize(() => { const dataId = singleKenStream.key; const randomKens = { ...this.state.randomKens }; delete randomKens[dataId]; this.setState({ randomKens }); }) )
  97. 97. const kenHead$ = this.socket$.pipe { groupBy(data => data.id), mergeMap(singleKenStream => singleKenStream.pipe( takeUntil( timer(3000), ), finalize(() => { const dataId = singleKenStream.key; const randomKens = { ...this.state.randomKens }; delete randomKens[dataId]; this.setState({ randomKens }); }) ) ) );
  98. 98. this.subscription = kenHead$.subscribe(data => { this.setState({ randomKens: { ...this.state.randomKens, [data.id]: { id: data.id, x: data.x, y: data.y } } }); }); componentWillUnmount() { this.subscription.unsubscribe(); }
  99. 99. render() { return ( <View> {Object.values(this.state.randomKens).map(randomKen => <Image key={randomKen.id} source={kenwheeler} style={{ position: ‘absolute’, left: randomKen.x, top: randomKen.y, }} /> )} <Button onPress={() => this.requestKenHead()} title=”add a ken bobble” /> </View> );
  100. 100. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we talked about today
  101. 101. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we talked about today
  102. 102. @ladyleet Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier Things we talked about today
  103. 103. @ladyleet Things we talked about today Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier
  104. 104. @ladyleet Things we talked about today Reactive programming in standards Reactive programming in frameworks & libraries How to think reactively What is RxJS? How reactive programming makes development easier
  105. 105. @ladyleet Click handlers AJAX requests Anything async …or just call subscribe? Easy ways to integrate RxJS
  106. 106. @ladyleet RxJS docs - come contribute! https://github.com/reactivex/rxjs
  107. 107. @ladyleet Thank you! Come hang with me on Twitter! http://twitter.com/ladyleet Grumpy cat game in Angular https://github.com/ladyleet/grumpycat-rx-ng-neww Bobble head Ken Wheeler react native app https://github.com/ladyleet/ken-wheeler-react-native-multi-plex-web-socket Node.js web socket server https://github.com/ladyleet/ws-server

×