Jafar Husain is Netflix's Cross-Team Technical Lead. He's currently a member of the TC39, the standards body designing the next version of JS. He specializes in functional reactive programming.
- 12:17 - 21:46 Creating Collections Jafar demonstrates how to use the functions he introduced in the previous section to create useful collections from a data source. He then applies the same code to a mouse-drag scenario to illustrate that events can be handled in the same manner.
- 21:47 - 32:56 Iterators and Observers Events and Arrays are both collections, just with different interfaces. Arrays use an iterator pattern. Events use an observer pattern. Jafar explains why he believes these two patterns are similar and why Events and Arrays should be handled in the same way.
32:57 - 43:37
- 43:38 - 50:10 Observable Metaphor While addressing an audience question, Jafar provides a real-world metaphor to further explain the difference between observers and iterators. He also walks through the implementation of the Observable.fromEvent() method.
- 50:11 - 01:02:40 Observables in Action Jafar demonstrates how Observables would work with the functions he introduced earlier. He runs examples using map(), filter(), and concatAll() and talks about the results.
- 01:02:41 - 01:10:59 Race Conditions and Nested Observables Using observables can help eliminate race conditions since they sequence the incoming streams. They also are able to handle scenarios with nested observables (observables of observables). Jafar revisits his cake-cutting scenario to further explain nested observables.
- 01:11:00 - 01:21:19 TakeUntil The takeUntil method copies all the data from a source observable into a new observable. However it completes once it reaches a “stop observable” which is passed as a parameter. This allows a seemingly infinite stream of data become finite.
- 01:21:20 - 01:28:48 Implementing Mouse Move Now that Jafar has covered the concatAll() and takeUntil() methods, he revisits the mouse-move code. This demonstrates how user interface events can be reduced to simple collections and handled in a similar way to arrays.
- 01:28:49 - 01:41:10 MergeAll & SwitchLatest The mergeAll() method functions similarly to the concatAll() method except that mergeAll will combine subsequent observables without waiting for a previous one to complete. Jafar explains why mergeAll can be useful and also covers the final flattening patter, switchLatest().
- 01:41:11 - 01:54:38 Netflix Search Box Jafar combines all the techniques he’s discussed up to this point to illustrate how to build the Netflix auto-suggest search box. The box will throttle key presses to limit network request and concatenate the received data until a new observable comes along.
- 01:54:39 - 02:08:58 Optimizing the Search Jafar spends a couple minutes talking about an optimized version of the search box code. He also explains the purpose of the retry method. Jafar also answers a number of audience questions about the different methods in this example.
- 02:08:59 - 02:20:12 Three-Dimensional Collections Using the Netflix player example from earlier in the course, Jafar walks through the code that takes the tangled callback version of the player and converts it into a clean, three-dimensional collection.
Creating Array Functions
02:20:13 - 02:32:37
Jafar introduces the exercises and guides the class through the first five which lead up to implementing a map function. Each exercise is written and run in the browser. If an exercise is completed correctly, it will reveal the next exercise.
- 02:32:38 - 02:46:36 Exercises 6-11 The next set of exercises involve filtering and flattening. Jafar demonstrates how to implement the filter and concatAll functions which can be used in more complex chaining. This leads to exercise 11 which requires the use of both map and concatAll.
- 02:46:37 - 03:04:33 Exercise 12 In exercise 12, you will retrieve the id, title, and box art URL for every video in the collection. Before beginning the exercise, Jafar gives a few instructions to ensure only asynchronous-compatible code will be used.
- 03:04:34 - 03:11:05 Exercises 13-14 In exercise 13, you will create a concatMap function that can be used to simplify consecutive concat/map calls. Exercise 14 puts this new function to use.
- 03:11:06 - 03:24:02 Exercises 15-17 In these exercises, you will begin working with a reduce function. The reduce function performs operations on array items at the same time as opposed to one item at a time.
- 03:24:03 - 03:38:38 Exercises 18-19 Exercise 18 involves using both the reduce and map functions to reduce multiple boxart objects to a single value. Exercise 19 demonstrates how to have the reduce function return a different type than the accumulator. Jafar also talks briefly about prototypical inheritance.
- 03:38:39 - 03:42:59 Exercise 20 Exercise 20 combines many of the functions implemented in earlier exercises including reduce, filter, and concatMap.
- 03:43:00 - 03:50:21 Exercises 21-23 When information is organized based on its position in an array, a zipping operation may be required to combine elements from equal positions in each array. Exercise 21 explains the need for zipping, exercise 22 implements a custom zip function, and exercise 23 puts this new function to work.
- 03:50:22 - 04:02:02 Exercise 24 In exercise 24, you will retrieve each video’s id, title, middle interesting moment time, and smallest box art. This will require using most of the function created throughout all the exercises.
- 02:20:13 - 02:32:37 Exercises 1-5 Jafar introduces the exercises and guides the class through the first five which lead up to implementing a map function. Each exercise is written and run in the browser. If an exercise is completed correctly, it will reveal the next exercise.
- 04:02:03 - 04:08:55 Debugging Async Jafar spends a few minutes talking about debugging. When working with asynchronous code, step-into and step-over statements are not always as effective. Jafar suggests using the debugger directive and setting breakpoints.
- 04:17:59 - 04:24:00 Exercise 25 Exercise 25 puts all five of the operators created in earlier exercises to use. The task is to convert Array data into tree structures that possess parent-child relationships.
- 04:24:01 - 04:38:32 Exercise 26a Jafar begins the lengthy 26th exercise by setting up the multiple levels of mapping required. He also gives a few tips about logging progress before running any concatenation. This makes it easier to verify all the desired data has been pulled into the collection correctly.
- 04:38:33 - 04:47:48 Exercise 26b Jafar finishes exercise 26 by zipping the some of the nested datasets to form the final collection.
- 04:47:49 - 04:56:58 Exercise 27 Exercise 27 marks the first exercise where live, asynchronous data is queried. The stock ticker will continuously log the data as new packets arrive.
Handling Events with Observables
- 04:56:59 - 05:05:56 Exercises 28-30 These exercises demonstrate how to transition from using explicit DOM events to Observables. Jafar also introduces the take function which will automatically dispose the subscription to the Observable after it has completed.
- 05:05:57 - 05:13:14 Exercise 31 Exercise 31 introduces the takeUntil function which will continue to pull data from a stream until a stop observable is encountered. Similarly to the take function, takeUntil will also dispose once the stopping point is reached.
- 05:13:15 - 05:22:57 Observables and Events Before starting exercise 32, Jafar spends some time explaining how to respond to UI events wrapped in Observables. Execution code is placed inside a forEach so it can be run each time a new event is added to the collection.
- 05:22:58 - 05:34:55 Anatomy of an Observable Jafar reviews the anatomy of an Observable. An Observable is nothing more than an object with a forEach function. The observer referenced when creating the Observable will have onNext, onError, and onCompleted functions.
- 05:46:45 - 05:59:53 Observables vs. Promises Jafar describes the differences between Observables and Promises. He also spends a few minutes talking about how Observables compare to Node streams and what Observables may look like in ES7.
- 05:59:54 - 06:06:10 Exercise 32 In this exercise, you will create a mouse drag event using Observables. To do this, you will retrieve only the mouse down events that occur before the next mouse up event.
- 06:06:11 - 06:13:31 Exercise 33 Jafar points out the mouse drag code in the previous exercise has a couple issues. The mouse snaps to the upper left corner of the object whenever it is grabbed. Jafar uses the offsetX and offsetY properties to fix this issue.
Handling HTTP Requests with Observables
- 06:13:32 - 06:23:42 Exercise 34 Most HTTP requests are exposed through a callback API. This exercise demonstrates how to use the getJSON method in jQuery to load remote data and handle success/error events. Jafar also begins building a larger example that will wrap the getJSON method in an Observable. First, he needs to get input from the user.
- 06:23:43 - 06:31:38 Searching Wikipedia Jafar uses JSONP to perform a search using the Wikipedia API because it will bypass any cross-origin issues. While his search function is still using callbacks, it demonstrates the API is working and allows him to them move it from a callback to an Observable.
- 06:31:39 - 06:37:52 JSONP as an Observable Now that Jafar has a working JSONP call, he converts it into an Observable. This creates the forEach and dispose functions required for subscribing to the Observable. When JSON data is received, the Observable calls the onNext and onCompleted.
- 06:37:53 - 06:48:29 Composing a Stream As the forEach function is called on the JSONP Observable, Jafar breaks down what the incoming data is going to look like to better explain which functions will be necessary to compose the stream.
- 06:48:30 - 06:58:52 Displaying Autocomplete Data Jafar uses the map and switchLatest functions to compose the search results into a dataset that will populate the autocomplete box. The switchLatest function is the key for optimizing the behavior since it will dispose any of the previous requests.
- 06:58:53 - 07:06:07 distinctUntilChanged() To further optimize the search suggestions, Jafar what only changed values to be sent to the server. While there are a number of ways to implement this, he chooses to introduce the RX.distinctUntilChanged function which will only update the stream when a change has occurred.
- 07:06:08 - 07:15:00 Catching Errors Jafar demonstrates how to handle errors that may occur when making network requests. The error handler is passed as the second parameter to the forEach and the retry function can be used to designate the number of attempts the Observable should make. This error handler will get called if after the desired number of attempts has been reached.
- 07:15:01 - 07:21:55 Handling Empty Searches After answering a few audience questions, Jafar further optimizes the code by only performing searches when the search text is not empty. He uses the filter function to check for values
- 07:21:56 - 07:30:07 Showing the Search Box Jafar modifies the user interface so the search box is hidden by default and will be shown when the user clicks a Search button. This will allow him to demonstrate how to make the search subscription dependent on the search button being clicked.
- 07:30:08 - 07:42:51 Close Button Observable After adding a close button to the search form, Jafar wants the click event from that button to dispose the current search stream and hide the form. To do this, he creates an observable from the click event and uses it in a takeUntil function.
- 07:42:52 - 07:55:26 Completing the Close Button Jafar adds the correct functionality to the close button so it will hide the form, thus disposing the current stream of server request. He also talks for a few minutes about how to introduce side effects during the forEach cycle with the doAction function.
- 07:55:27 - 08:01:21 Audience Questions Before moving on, Jafar spends takes some time to answer audience questions about the behavior of the form and some other general questions about Observables.
- 08:01:22 - 08:12:31 Creating an Observable Class Up to this point, Jafar has been using the Observable class from the RX library. To better explain how Observables work under the hood, he creates an Observable class from scratch and implements the forEach and fromEvent functions.
- 08:12:32 - 08:21:49 Observable Map Function Jafar revisits the implementation for the map function. Only this time, instead of adding it to the Array class, he implements it on the Observable class. Since it is on the Observable class, map will call onNext and pass the appropriate projection function.
- 08:21:50 - 08:30:09 Observable Filter Function The Observable filter function has a similar implementation to the map function. Jafar leads the group through adding this function and explains the public forEach function with a little more detail.
- 08:30:10 - 08:40:55 Using the Observable Class Now that Jafar has created his own Observable class with a map and filter function, he builds a simple program to see it in action. When a button is clicked, he transforms the mouse position value with the map function and returns a filtered result.
08:40:56 - 08:54:08
Observable Take Function
The Object.observe API will be landing in ES7. While it does allow developers to monitor for changes in variables, the API has its pitfalls. Jafar demonstrates how this API can be recreated as an Observable by implementing the take function.
- 08:54:09 - 09:06:00 Implementing a Better Object.observe With the take function implemented, Jafar uses it to convert the Object.observe function into an Observable. This allows him to fix some of the pitfalls in the API.
- 09:06:01 - 09:16:27 Binding Between Views and Models Jafar puts his new Observable based on the Object.observe API to work by creating a two-way binding between the model data and the view. If the view is updated, the changes propagate to the model. If the model is updated, the changes are reflected in the view.
- 09:16:28 - 09:26:36 Syncing Data with the Server While two-way binding in the application is nice, the changes reflected in the model and view should also be synchronized with the database. Jafar expands his example to include a database request as the model data is changed.
- 09:26:37 - 09:36:39 Observables as Animations Jafar wraps up the course talking about how Observables can be used to sequence animations in a user interface. He also revisits the concept of syncing data with a database.