Rxjs in Action
Total Page:16
File Type:pdf, Size:1020Kb
Paul P. Daniels Luis Atencio FOREWORD BY Ben Lesh MANNING www.allitebooks.com RxJS in Action www.allitebooks.com www.allitebooks.com RxJS in Action COVERS RXJS 5 PAUL P. DANIELS LUIS ATENCIO FOREWORD BY BEN LESH MANNING SHELTER ISLAND www.allitebooks.com For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: [email protected] ©2017 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Development editor: Frances Lefkowitz 20 Baldwin Road Technical development editor: Dean Iverson PO Box 761 Project editor: Janet Vail Shelter Island, NY 11964 Copyeditor: Linda Recktenwald Proofreader: Katie Tennant Technical proofreader: Cody Sand Typesetter: Dottie Marsico Cover designer: Marija Tudor ISBN 9781617293412 Printed in the United States of America 12345678910–EBM–222120191817 www.allitebooks.com brief contents PART 1UNDERSTANDING STREAMS 1 1 ■ Thinking reactively 3 2 ■ Reacting with RxJS 28 3 ■ Core operators 61 4 ■ It’s about time you used RxJS 85 PART 2OBSERVABLES IN PRACTICE 119 5 ■ Applied reactive streams 121 6 ■ Coordinating business processes 151 7 ■ Error handling with RxJS 182 PART 3MASTERING RXJS 209 8 ■ Heating up observables 211 9 ■ Toward testable, reactive programs 245 10 ■ RxJS in the wild 271 v www.allitebooks.com www.allitebooks.com contents foreword xiii preface xv acknowledgments xvii about this book xix about the authors xxiv about the cover xxv PART 1UNDERSTANDING STREAMS.................................1 Thinking reactively 3 1 1.1 Synchronous vs. asynchronous computing 5 Issues with blocking code 5 ■ Non-blocking code with callback functions 6 ■ Understanding time and space 7 Are callbacks out of the picture? 9 ■ Event emitters 11 1.2 Better callbacks with Promises 12 1.3 The need for a different paradigm 14 1.4 The Reactive Extensions for JavaScript 17 Thinking in streams: data flows and propagation 17 Introducing the RxJS project 18 ■ Everything is a stream 19 ■ Abstracting the notion of time from your programs 21 ■ Components of an Rx stream 23 1.5 Reactive and other programming paradigms 26 1.6 Summary 27 vii www.allitebooks.com viii CONTENTS Reacting with RxJS 28 2 2.1 Functional programming as the pillar of reactive programming 29 Functional programming 30 ■ The iterator pattern 38 2.2 Stream’s data-driven approach 41 2.3 Wrapping data sources with Rx.Observable 43 Identifying different sources of data 43 ■ Creating RxJS observables 44 ■ When and where to use RxJS 46 To push or not to push 49 2.4 Consuming data with observers 53 The Observer API 53 ■ Creating bare observables 55 Observable modules 57 2.5 Summary 60 Core operators 61 3 3.1 Evaluating and cancelling streams 62 Downside of eager allocation 62 ■ Lazy allocation and subscribing to observables 64 ■ Disposing of subscriptions: explicit cancellation 65 ■ Cancellation mismatch between RxJS and other APIs 67 3.2 Popular RxJS observable operators 69 Introducing the core operators 70 3.3 Sequencing operator pipelines with aggregates 77 Self-contained pipelines and referential transparency 77 Performance advantages of sequencing with RxJS 80 3.4 Summary 83 It’s about time you used RxJS 85 4 4.1 Why worry about time? 87 4.2 Understanding asynchronous timing with JavaScript 88 Implicit timing 88 ■ Explicit timing 88 ■ The JavaScript timing interfaces 90 4.3 Back to the future with RxJS 94 Propagation 98 ■ Sequential time 99 4.4 Handling user input 101 Debouncing 101 ■ Throttling 108 4.5 Buffering in RxJS 111 4.6 Summary 116 www.allitebooks.com CONTENTS ix PART 2OBSERVABLES IN PRACTICE ............................119 Applied reactive streams 121 5 5.1 One for all, and all for one! 122 Interleave events by merging streams 124 ■ Preserve order of events by concatenating streams 130 ■ Switch to the latest observable data 133 5.2 Unwinding nested observables: the case of mergeMap 135 5.3 Mastering asynchronous streams 141 5.4 Drag and drop with concatMap 146 5.5 Summary 150 Coordinating business processes 151 6 6.1 Hooking into the observable lifecycle 152 Web hooks and the observer pattern 153 Hooked on observables 154 6.2 Joining parallel streams with combineLatest and forkJoin 159 Limitations of using Promises 162 ■ Combining parallel streams 163 ■ More coordination with forkJoin 168 6.3 Building a reactive database 170 Populating a database reactively 172 ■ Writing bulk data 175 ■ Joining related database operations 177 ■ Reactive databases 180 6.4 Summary 181 Error handling with RxJS 182 7 7.1 Common error-handling techniques 183 Error handling with try/catch 183 ■ Delegating errors to callbacks 184 ■ Errors and Promises 186 7.2 Incompatibilities between imperative error-handling techniques and functional and reactive code bases 188 7.3 Understanding the functional error-handling approach 189 7.4 The RxJS way of dealing with failure 193 Errors propagated downstream to observers 193 Catching and reacting to errors 195 ■ Retrying failed www.allitebooks.com x CONTENTS streams for a fixed number of times 197 ■ Reacting to failed retries 199 7.5 Summary 208 PART 3MASTERING RXJS ..........................................209 Heating up observables 211 8 8.1 Introducing hot and cold observables 212 Cold observables 212 ■ Hot observables 215 8.2 A new type of data source: WebSockets 217 A brief look at WebSocket 218 ■ A simple WebSocket server in Node.js 219 ■ WebSocket client 220 8.3 The impact of side effects on a resubscribe or a replay 221 Replay vs. resubscribe 222 ■ Replaying the logic of a stream 222 ■ Resubscribing to a stream 224 8.4 Changing the temperature of an observable 226 Producers as thermometers 227 ■ Making a hot observable cold 228 ■ Making a cold observable hot 230 ■ Creating hot-by-operator streams 232 8.5 Connecting one observable to many observers 237 Publish 237 ■ Publish with replay 240 Publish last 242 8.6 Summary 243 Toward testable, reactive programs 245 9 9.1 Testing is inherently built into functional programs 246 9.2 Testing asynchronous code and promises 250 Testing AJAX requests 250 ■ Working with Promises 253 9.3 Testing reactive streams 255 9.4 Making streams testable 258 9.5 Scheduling values in RxJS 260 9.6 Augmenting virtual reality 263 Playing with marbles 264 ■ Fake it ’til you make it 266 Refactoring your search stream for testability 267 9.7 Summary 270 CONTENTS xi RxJS in the wild 271 10 10.1 Building a basic banking application 273 10.2 Introduction to React and Redux 274 Rendering UI components with React 274 State management with Redux 284 10.3 Redux-ing application state 286 Actions and reducers 286 ■ Redux store 287 10.4 Building a hot RxJS and Redux store adapter 290 10.5 Asynchronous middleware with RxJS Subject 291 RxJS subjects 294 ■ Building epic, reactive middleware 296 10.6 Bringing it all home 302 10.7 Parting words 304 10.8 Summary 304 appendix A Installation of libraries used in this book 305 appendix B Choosing an operator 310 index 315 foreword It’s no secret that the web has grown dramatically in popularity as a platform for build- ing large-scale, high-traffic applications. Modern web applications are somewhat unique in the computing world, however, because they require a great deal of asyn- chrony, ranging from AJAX requests to animations to lazy-loaded client resources and multiplexed web sockets. And all this asynchrony comes with a complexity cost. A simple drag and drop, for example, is actually a coordination of three or more different events: wait for a mouse-down and then listen to all mouse movements until the next mouse-up. Current imperative approaches to implement this sort of thing are not always straightforward; they’re difficult to maintain, and they’re rarely bug free. RxJS is an ideal tool to help you manage asynchronous complexity in your applica- tions in a declarative, easy-to-maintain, and fun way. So how do you learn Rx? This book, RxJS in Action, is to date the only resource of its type to cover the latest version, RxJS 5. As the project lead for RxJS, I’m very happy to see this book reach the masses with important information you need to know about this library in order to be an effective reactive programmer. —Ben Lesh Project lead, RxJS 5 xiii preface We wrote this book to help you understand the power and significance of reactive pro- gramming in JavaScript and develop the skills to put RxJS to work. FROM PAUL: Like many skills, RxJS was not something I had originally set out to learn but instead something I stumbled on and continued in, only because of a confluence of events. Earlier in my programming career, I had been working on a new UI system for an internal tool in which the project owner had given me a large degree of latitude regarding what technologies I employed.