+ All Categories
Home > Technology > Asynchronous JavaScript at Netflix

Asynchronous JavaScript at Netflix

Date post: 26-Jan-2015
Category:
Upload: tim-jurka
View: 112 times
Download: 0 times
Share this document with a friend
Description:
Netflix's Jafar Husain shares how the company is using the Reactive Extensions (Rx) library to build responsive UIs across their device experiences.
Popular Tags:
56
Async JavaScript at Netflix Jafar Husain jhusain@netflix .com
Transcript
Page 1: Asynchronous JavaScript at Netflix

Async JavaScript at Netflix

Jafar [email protected]

Page 2: Asynchronous JavaScript at Netflix

Who am I?Cross-Team Technical Lead for the Netflix UIs

13 years in the industry, formerly worked at Microsoft and GE

6 years of experience building large systems with Functional Reactive Programming

Page 3: Asynchronous JavaScript at Netflix

This is the story of how Netflix solved

BIG async problems

by thinking differently about

Events.

Page 4: Asynchronous JavaScript at Netflix

2014321

Page 5: Asynchronous JavaScript at Netflix

Our App is AsynchronousApp StartupPlayerData AccessAnimationsView/Model binding

Page 6: Asynchronous JavaScript at Netflix

Async ProblemsMemory LeaksRace ConditionsCallback HellComplex state machinesError Handling

Page 7: Asynchronous JavaScript at Netflix

Async is Hardfunction play(movieId, cancelButton, callback) { var movieTicket, playError, tryFinish = function() { if (playError) { callback(null, playError); } else if (movieTicket && player.initialized) { callback(null, ticket); } }; cancelButton.addEventListener(“click”, function() { playError = “cancelled”; } if (!player.initialized) { player.init(function(error) { playError = error; tryFinish(); } } authorizeMovie(function(error, ticket) { playError = error; movieTicket = ticket; tryFinish(); });});

function play(movieId, cancelButton, callback) { var movieTicket, playError, tryFinish = function() { if (playError) { callback(null, playError); } else if (movieTicket && player.initialized) { callback(null, ticket); } }; cancelButton.addEventListener(“click”, function() { playError = “cancelled”; } if (!player.initialized) { player.init(function(error) { playError = error; tryFinish(); }); } authorizeMovie(function(error, ticket) { playError = error; movieTicket = ticket; tryFinish(); });});

function play(movieId, cancelButton, callback) { var movieTicket, playError, tryFinish = function() { if (playError) { callback(null, playError); } else if (movieTicket && player.initialized) { callback(null, ticket); } }; cancelButton.addEventListener(“click”, function() { playError = “cancelled”; } if (!player.initialized) { player.init(function(error) { playError = error; tryFinish(); }); } authorizeMovie(function(error, ticket) { playError = error; movieTicket = ticket; tryFinish(); });});

function play(movieId, cancelButton, callback) { var movieTicket, playError, tryFinish = function() { if (playError) { callback(null, playError); } else if (movieTicket && player.initialized) { callback(null, ticket); } }; cancelButton.addEventListener(“click”, function() { playError = “cancelled”; } if (!player.initialized) { player.init(function(error) { playError = error; tryFinish(); } } authorizeMovie(function(error, ticket) { playError = error; movieTicket = ticket; tryFinish(); });});

Page 8: Asynchronous JavaScript at Netflix
Page 9: Asynchronous JavaScript at Netflix
Page 10: Asynchronous JavaScript at Netflix

Iterator

Observer

progressively send information to consumer

Page 11: Asynchronous JavaScript at Netflix
Page 12: Asynchronous JavaScript at Netflix

“What’s the difference between an Array…

[{x: 23, y: 44}, {x:27, y:55}, {x:27, y:55}]

Page 13: Asynchronous JavaScript at Netflix

… and an Event?

{x: 23, y: 44}...{x:27, y:55}.... {x:27, y:55}......

Page 14: Asynchronous JavaScript at Netflix

Events and Arrays are both collections.

Page 15: Asynchronous JavaScript at Netflix

Now for a brief

JavaScript 6 tutorial…

Page 16: Asynchronous JavaScript at Netflix

Functions

x + 1function(x) { return x + 1; }x =>function(x, y) { return x + y; }(x,

y)x + y =>

JS65

Page 17: Asynchronous JavaScript at Netflix

Fin.

Page 18: Asynchronous JavaScript at Netflix

The majority of Netflix’s async code is written with just a few

flexible functions.

Page 19: Asynchronous JavaScript at Netflix

ForEach

> [1, 2, 3].forEach(x => console.log(x))> 1> 2> 3>

Page 20: Asynchronous JavaScript at Netflix

Map

Page 21: Asynchronous JavaScript at Netflix

Map

> [1, 2, 3].map(x => x + 1)> [2, 3, 4]>

Page 22: Asynchronous JavaScript at Netflix

Filter

Page 23: Asynchronous JavaScript at Netflix

Filter

> [1, 2, 3].filter(x => x > 1)> [2, 3]>

Page 24: Asynchronous JavaScript at Netflix

concatAll

Page 25: Asynchronous JavaScript at Netflix

concatAll

> [ [1], [2, 3], [], [4] ].concatAll()> [1, 2, 3, 4]>

Page 26: Asynchronous JavaScript at Netflix

Map/Filter/ConcatAll> [1, 2, 3].map(x => x + 1)> [2, 3, 4]

> [1, 2, 3].filter(x => x > 1)> [2, 3]

> [ [1], [2, 3], [], [4] ].concatAll()> [1, 2, 3, 4]>

Page 27: Asynchronous JavaScript at Netflix
Page 28: Asynchronous JavaScript at Netflix

Let’s use map, filter, and concatAll to get a list of your favorite Netflix titles.

Page 29: Asynchronous JavaScript at Netflix

Top-rated Movies Collection

var getTopRatedFilms = user => user.videoLists. map(videoList => videoList.videos. filter(video => video.rating === 5.0)). concatAll();

getTopRatedFilms(user). forEach(film => console.log(film));

Page 30: Asynchronous JavaScript at Netflix

What if I told you……that you could create a drag event…

…with nearly the same code?

Page 31: Asynchronous JavaScript at Netflix

Top-rated Movies Collection

var getTopRatedFilms = user => user.videoLists. map(videoList => videoList.videos. filter(video => video.rating === 5.0)). concatAll();

getTopRatedFilms(user). forEach(film => console.log(film));

Page 32: Asynchronous JavaScript at Netflix

Mouse Drags Collection

var getElementDrags = elmt => elmt.mouseDowns. map(mouseDown => document.mouseMoves. filter takeUntil(document.mouseUps)). concatAll();

getElementDrags(image). forEach(pos => image.position = pos);

Page 33: Asynchronous JavaScript at Netflix

Observable === Collections + Time

Introducing Observable

Page 34: Asynchronous JavaScript at Netflix

Reactive ExtensionsObservable Type + Array Functions (and more)

Open SourcePorted to…

CC#/VB.Net Javascript Java (Netflix)

Page 35: Asynchronous JavaScript at Netflix

Observables can model…EventsData requestsAnimations

Page 36: Asynchronous JavaScript at Netflix

Events to Observables

var mouseMoves = Observable. fromEvent(element, “mousemove”);

Page 37: Asynchronous JavaScript at Netflix

Event Subscription

// “subscribe”var handler = (e) => console.log(e);document.addEventListener(“mousemoves”, handler);

// “unsubscribe”document.removeEventListener(“mousemoves”, handler);

Page 38: Asynchronous JavaScript at Netflix

Observable.forEach

// “subscribe”var subscription = mouseMoves.forEach(console.log);

// “unsubscribe”subscription.dispose();

Page 39: Asynchronous JavaScript at Netflix

Expanded Observable.forEach// “subscribe”var subscription = mouseMoves.forEach( // next data event => console.log(event), // error error => console.error(error), // completed () => console.log(“done”));

// “unsubscribe”subscription.dispose();

optional

Page 40: Asynchronous JavaScript at Netflix

Observable Literal

JS6

time

{1……2…………3}

Page 41: Asynchronous JavaScript at Netflix

ForEach

> {1……2…………3}.forEach(console.log)

> 1>> 2>> 3>

time

> {1……2…………3}

Page 42: Asynchronous JavaScript at Netflix

Map

> {1……2…………3}.map(x => x + 1)

> 2>> 3>> 4>

time

Page 43: Asynchronous JavaScript at Netflix

> 2> 3>

Filter

> {1……2…………3}.filter(x => x + 1)

> > 2>

time

Page 44: Asynchronous JavaScript at Netflix

concatAll

[ [1] [2, 3], [], [4]].concatAll()

[1, 2, 3, 4]

Page 45: Asynchronous JavaScript at Netflix

concatAll

{…{1}………{2………………3}, ……………{}………………{4}}.concatAll()

{…1…2………………3…4}

time

Page 46: Asynchronous JavaScript at Netflix

TakeUntil

{…1…2…………3}.takeUntil({……………4})

{…1…2…}

timeSource collection

Stop collection

Page 47: Asynchronous JavaScript at Netflix

Don’t unsubscribe from Events.

Complete them when another event fires.

Page 48: Asynchronous JavaScript at Netflix

Mouse Drags Collection

var getElementDrags = elmt => elmt.mouseDowns. map(mouseDown => document.mouseMoves. takeUntil(document.mouseUps)). concatAll();

getElementDrags(image). forEach(pos => image.position = pos);

Page 49: Asynchronous JavaScript at Netflix

Netflix Search

Page 50: Asynchronous JavaScript at Netflix

Netflix Searchvar searchResultSets = keyPresses. throttle(250). map(key => getJSON(“/searchResults?q=” + input.value). retry(3). takeUntil(keyPresses)). concatAll();

searchResultSets.forEach( resultSet => updateSearchResults(resultSet), error => showMessage(“the server appears to be down.”));

Page 51: Asynchronous JavaScript at Netflix

Netflix Player

Page 52: Asynchronous JavaScript at Netflix

Player Callback Hellfunction play(movieId, cancelButton, callback) { var movieTicket, playError, tryFinish = function() { if (playError) { callback(null, playError); } else if (movieTicket && player.initialized) { callback(null, ticket); } }; cancelButton.addEventListener(“click”, function() { playError = “cancel”; }); if (!player.initialized) { player.init(function(error) { playError = error; tryFinish(); } } authorizeMovie(movieId, function(error, ticket) { playError = error; movieTicket = ticket; tryFinish(); });});

Page 53: Asynchronous JavaScript at Netflix

Player with Observablevar authorizations = player. init(). map(() => playAttempts. map(movieId => player.authorize(movieId). retry(3). takeUntil(cancels)). concatAll())). concatAll(); authorizations.forEach( license => player.play(license), error => showDialog(“Sorry, can’t play right now.”));

Page 54: Asynchronous JavaScript at Netflix

Netflix: Observable EverywhereApp StartupPlayerData AccessAnimationsView/Model binding

Page 55: Asynchronous JavaScript at Netflix

Resources https://github.com/Reactive-Extensions/RxJS RxJava http://jhusain.github.io/learnrx/

Page 56: Asynchronous JavaScript at Netflix

Questions


Recommended