Introducing RxJS6! - Ben Lesh

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
how's it going everybody so this this talk is called introducing arcs gs6 I'm Ben Lesh has already introduced I am an engineer at Google I am the rxjs lead and I just recently joined the the angular team all right here's thank you very much so here's one of the benefits of joining the angular team you get to watch Igor do handstands this is a view for my desk he literally does this like three times a day it's amazing this is this is for me this is the biggest what's new in RCS and and that's because for more than a year probably about a year and a half now rxjs has been a hundred percent volunteer work almost two hundred percent volunteer work you know a lot of really good people working after hours sacrificing time with their families working on this and we had a lot of really great help actually the only person in this list who's not a volunteer is front and center there Jason Hayden he's on the angular team and he's extremely helpful in making some of the backward compatibility stuff I'm gonna talk about in a little bit and what the angular team has been working on is they had me working on full time on rxjs and rxjs related angular functionality so that's that's really good news for the rxjs community even outside of angular and I'm really excited about it something that's really important the angular team all once once once everyone to know even outside of angular land that rxjs is going to remain an independent project and the decisions that I make on behalf of the rxjs team will be on behalf of all rxjs users not just specific to the angular team it's very important to everybody so thank you very much so I'm gonna apologize because I'm gonna go pretty quickly in 20 minutes I want to cover an awful lot of stuff so the first thing I want to talk about is what was new in rxjs 5 5 and that came out last year but it's really important when it comes to the migration path to rxjs 6 so there's a current stable version in past years whenever you were using rfcs 5 or 5 4 and under this is what we recommended the recommended usage was you would import observable and you would then add your methods add your operators and you would use them and this is fine with five five and up we recommended that people start importing the creation methods directly and using them like we're doing here with of and we also recommended that you import pipeable operators and use them inside the pipe method of observable so the question I get asked I've been asked in the hallway a few times here is why use pipe herbal operators the the big thing about pipe operators is what they're doing is they're patching the prototype and patching the prototype comes with a lot of problems the the problems are is very specifically that it's global so if you have a library that adds map to observable then everybody else that can that consumes that observable now also has the map method they might start relying on that and then the library removes it and guess what you broke everybody else that was relying on it so that's not good it's not tree shakable because there's a side effect of adding map to the prototype and the tree checkers don't really know what to do with that you could end up trampling somebody else's method say if I have a custom filter and then you add the RFDS filter then it's going to trample my filter and the other things is custom operators are much much easier to implement in use and I'm going to show that in a minute and also compilers and lint linters will give you a little bit more help if you import an operator and you don't use it a leaner your linter will complain and if you try to use an operator without importing it your compilers going to complain so here's what a custom Pipal operator looks like here I've got a POW operator and I'm gonna show how that that is actually used here in a second but basically you just create a higher-order function that returns a function that takes an observable and returns observable and this is the shape of all pipeable operators and you can use them with any other pipeable operator including filter here that comes from rxjs we're using our pal operator there and POW is just multiplying a number by itself some some number of times so the old way and i don't expect anybody to read this the old way you would have to do this without trampling things and the prototype would be to subclass observable add your pal method and then override lift and make sure the lift returns your custom observable your subclass observable again then you have to implement a pile operator and a POW subscriber it's a lot of work it's clearly a lot more code than then the other the other way was I think this has just died that's okay so that was what was new in our cs5 and how they recommend that you move to those because we're recommending that people use pipeable or pipeable operators in arcgis 6 that's how we're doing operators so rxjs 6 is now in release candidate I am actually looking at probably publishing the the final version of this today or sometime very very soon so new features in 6 so what's new in 6 is we've got new unhandled air behavior so this is a breaking change from 5 I'm going to talk about what that means in just a minute we also have simplified imports we've got some deprecations and some removals and we have a new operator but sorry the new operator is not that exciting everybody likes new stuff but I'll talk about it in a minute so the unhandled air behavior this is this one's important the the old way that we are doing things every version of previous version of rxjs did this was if you have an unhandled error which means an area that gets all the way to the down to the bottom of your chain of observation and you don't have an air handler there it's gonna wreath row that error synchronously and in the new version in arcgis 6 we're going to schedule that air to be wreath roan with like a set timeout so just just to give you example say i have this bad source this bad observable and what it's going to do is eventually it's going to throw an error and i didn't provide an air handler to it that second argument i just passed a null or maybe i have an observer that doesn't have an error method on it in this case if bad source happens to be totally synchronous which it could be I could actually wrap it in a try-catch in version 5 and under and catch the error as it's wreath roan from subscribe it would bubble all the way back out and I could catch it there and handle it which is kind of weird right because if bad source happens to be asynchronous someone changes the implementation whatever and observables are usually asynchronous then try-catch is not going to work and asynchronously thrown error cannot be caught with try catch period so the important thing is you with arcs for rxjs 6 you do not want to depend on that synchronous error wreath rowing for unhandled era so you don't want to depend on that it's not good we're removing it because it comes with problems so let's let's look at what you would have to do to refactor this bad pattern so so I here here's what we're doing here and you'll notice in inside my catch I've taken out all the logic of what we're doing in caching I've already kind of wrapped it in a method or in a function rather and what you can do is just move that function to the air handler it's actually even less code now and now it'll even handle errors if the error happens to be asynchronous so this will work in rxjs 6 so the moral of this story is the the code that's going to break when you upgrade to 6 around this was code that was expecting unexpected errors which is pretty amazing it sounds weird but there actually is code that might might do this on purpose you could have a test right you could have a test that expects when you subscribe to this observer you expected to throw some specific error synchronously this this test will break in rxjs 6 because that we no longer synchronous synchronously throw errors so to refactor this what you would end up having to do is here I'm just passing in an observer that has an error method on it so it's a little bit more explicit a little bit easier to read and then I'm I'm running I'm testing some expectations against my err object that I've got and I'm calling done I'm actually making it an asynchronous tests so now it'll even cover situations where bad source might be asynchronous so this is a little bit better to do and it'll work in 6 so the question then becomes but why why did we change the error throwing behavior there's this little thing called producer interference and it's one of the nastiest bugs that you'll ever come across because it's like a cross team sort of bug that you'll see and I ran into this at Netflix and it was one of the reasons why there was discussions with the tc39 about why we're gonna change this behavior even in the observable proposal so just to give an example we're just we're gonna say that we have this third-party services my Jeff cross service it's important to name things after your friends it's always good so Jeff Jeff Croft sir Jeff Cross service is this is what the interface is like I'm not gonna get into the implementation yet but basically it's just got this get amazing stuff method that returns and of numbers and we're going to use this amongst a bunch of different consumers so our first consumer is the lady leet component and all the lady of the components doing is using the Jeff cross service to get our observable of numbers and filtering out trying to get all the numbers that are less than 50 and display them in some template our second consumer is shy component and shai's chose mean he's he's written this component and he's not really filtering out anything he's just using filter to be like hey if I get the value 42 I'm gonna throw an error shy come on man then we have mieszko component he's basically doing the opposite of what the ladylee component is doing he wants all the values that are higher than 50 from the Jeff Jeff cross service so we get a bug report about this p0 no one knows what's going on the meet the mieszko component randomly stops showing data and they looked there's a hundred percent code coverage all integration tests passed nothing looks like it's wrong with the michiko service it's too simple it only happens in production and they suspect the Jeff cross services to blame they don't know what it is so tasked with looking at this so let's go look at the Jeff cross service it's pretty simple it's all it is is we've got this observable stream of it's an interval it's going on an interval where we're mapping that to a random number between a random integer between 0 and 100 and we're sharing it so we're multi casting it so this doesn't look like there could be much wrong with this either but I guarantee this is going to cause our producer interference problem so what happened Jeff draw service returns a shared multicast observable multi casting loops over an array of observers and notifies each one of them by calling their next method and that then calls other functions down your chain of observation shai component synchronously throws an error if it happens to get the number 42 if the synchronous error goes all the way down in the chain of observation and is unhandled there's no air handler then it's synchronous leary thrown which means that javascript is going to take over and be like oh well I'm gonna unwind the stack looking for a try-catch to handle my error it unwinds the stack all the way back to the for loop that's notifying all the observers and what happens when you throw an air in a for-loop the air the for loop stops it's done and then Michiko sat he doesn't get his data and since he was the next one in that group of consumers it's gonna look like that components the problem so imagine if different teams developed these components and a separate team developed the service like figuring out who is to blame for this problem it's a very very nasty bug to run across unless you happen to have me working with you you might have a problem so I actually have this example you can explore it when I get the slides out you'll be able to just go to the stack blitz and try it out for yourself and see what the air what the air looks like arcs gs6 solves this problem by scheduling the the errors the unhandled airs to be Reath rone in a set timeout just like this the the lingo for this is called host report errors and what this does is it throws in its own call stack where it can't bubble up to hit anybody's try-catch and that means it's gonna get reported to window on error or process on air where you would expect unhandled errors to go if you still have issues with this there is a flag there this is call there's a you can pull and config and flip used deprecated synchronous error handling to true if you do that you will get a warning in console if any if any library in your system is doing that if you are a library owner do not do this because it is global so if you do it in your library you're affecting everybody else that's consuming rxjs and it's probably a peer dependency and that's not going to be good if you are an app owner you might it might have a large app and you're depending on synchronous air throwing and a lot of places for some reason if you're desperate you can you can try it out but just understand it's going to affect the behavior of some of your libraries that are consuming our xj6 so let's talk about the changes to imports the change of the imports this is how you import it things in version 5 so this is again the example I imported observable then I patch it with the different creation methods and the operators and I use it below in version 5.5 you can import each operator individually and then you can you can import the creation methods individually and use them like this you could also import all of the operators from one spot from our XG s slash operators and version five or five point five but the thing is we've got a lot of different import sites so here's a non-exhaustive list of v5 import sites so these are all like arcgis arcgis /rx is a kitchen sink ones you got observable and sub all the subjects you've got schedulers all the creation methods these are the operators in alphabetic order we're gonna go here's one page two pages two columns we only made it to F that's the sixth letter in the alphabet right so and there's there's multiple ways to import the operators too so there's hundreds in hundreds and hundreds of possible import sites in rxjs version five and it confuses people in rxjs version six there are roughly two that you'll care about as an angular developer you will import everything that is a type or a scheduler or a helper from our rxjs and all of the operators get imported from rxjs slash operators and that's it so here's the complete list of all the possible import sites the the top two I just told you about rxjs and RCS slash operators all of the testing stuff is under rxjs slash testing the WebSocket implementation is under RCS slash WebSocket and our the ArcGIS has its own Ajax implementation that nobody in the angular community really uses because you have the HTTP service that's under rxjs slash Ajax so again the two you care about just to go over it rxjs has all the types all the creation methods all of the schedulers all of the helpers under it basically anything that's not an operator comes from this pretty much and then all of the operators that you had passed a pipe come from rxjs slash operators let's talk about deprecations and removals the why so the reason that we're deprecating and removing certain things is because we had some exposed implementation details that people were using we also want to reduce the library size and we want to reduce the API surface area so the libraries a little bit easier for people to learn and use so right now we have too many ways to do the same thing these are all ways to do basically what observable of does you can import a Rea observable or scalar observable you can use them directly with new you could you could import from array use of I mean this is how you do use them these are all doing the exact same thing they even follow the same code paths in a lot of cases in rx gs6 there's there's only one way to do this you import of and you use it so no more of this which one do I use there's one implementation details that have been moved or removed so these are just as an example there's a lot of observables like some people were using empty observable or air observable are never observable directly you weren't really supposed to do that I think there's even some documentation out there that that recommends you do that it was never supposed to happen that way it's these were implementation details of the library that were to support the other methods that were recommending you use so there's probably some people that are using these are freaking out like oh god what do we do don't don't worry we've we've got something to help you I'll get to that at the end here so deprecations we're deprecating result selectors a lot of people don't even know what this is and I don't even think they were really documented that well it's this right here there's a set for merge map can cat maps which map in a few a few other operators there was a second mapping function you could use to map inner and outer observables or inner and outer values and omit them you can do the same thing by just using a pipe removing all of these result selectors resulted in removing almost two thousand lines of code from our code base so it's it's important now these are just deprecated we removed them but we're now doing what you're seeing here internal in the library if you're still using them but we're we want you by version seven to stop using these and start start doing this so so the other thing we're deprecating is the operator versions of concat and merge and zip and the ones that basically they have a counterpart that's static and the reason that we're removing them is there's a couple reasons but i'll get to in a second so here's what they look like in operator format you've got a pipe and cat b c if you use them statically it's just can cat a b c it's it's a lot easier to read so the the biggest reason we want to remove them is we don't want confusion between like here's a creation method and here's an operator and people try to use the creation method as an operator and it just breaks and you get this function is not an observable type weird error and that's that's not good so these are deprecated for now and by version seven we want to remove them all right the new the new operator so exciting throw up empty see I can tell you're excited the throw off empty what it does is it does exactly what it sounds like if an observable completes without emitting any values it will map a new error and throw it down the chain of observation if the observable gets a value then it's just a pass-through and this can be used in a variety of ways here's just a contrived example where we're saying take all the button clicks until someone resizes the view and if no one clicks the button before the views resize we're going to throw an error that said the button wasn't clicked before the views resize contrived but that's it so those are all the changes so great Ben how are we gonna migrate and update everything like I'm ruining someone's day right now well to to up to update to upgrade RCS what you can do is you can just if you're using yarn or NPM you can right now say rxjs at RC and later today it'll just be rxjs but very soon anyways and then right there you've already got our cs6 and things are gonna start breaking if you're using rxjs 5 features until you install rxjs - compat and what rxjs - compat is is it is a library that provides a bridge to all of the old import port sites and old types that existed in rxjs 5.5 you won't need the RC once we release so again that's coming very soon and if you're using the newest version of angular CLI it's even easier what you do there is you just do ng update RCS and that's because we've added schematics to the rxjs library a package itself that will run with with ng update and basically do the previous two steps I was showing for year so after that thank you very much after that like 90 99 percent of you would just be good to go even if you have the old rxjs 5 5 style as long as you do not do anything too crazy it should just work at that point so just a recap of how to migrate or update the first thing you want to do is update to 5 5 10 the latest version of 5 5 because there's there's some bug fixes in there and you want to make sure that you catch any bugs that came from those bug fixes first and then you and you update to 6 so update arcs you have 2 6 0 and then you can install rxjs - compat if you if you haven't already migrated all your code to be 6o compliant and then from there you want to go through and update your imports and your code to be 6o compliant and then you can remove arcs yes - can pat but headband there's a step in there that sounded horrible right like going through and updating all your code you don't want to do that no I don't want to do that either so when a Maiko who's who's here somewhere I didn't I have seen him around he and Vikram and a few other wonderful people at Google have helped put together this TS lint rule rxjs - TS lint and you can actually just install it add a migrate migrate TS lint json to your directory and all these instructions are in the readme for the TS lint rule and then run TS lint fix and it will go through and update all of your dot chained operators to be pipeable operators it'll update all of your observable loves to be just of it'll make everything 6o compliant for you you might have to run it more than once because there's some quirks around TS lint about it'll update it'll update everything and then you have to update everything again but after you run it a two or three times maybe everything will be updated I'm sorry about that it's kind of funny but everything will be updated and from there you can probably just remove the rxjs compat package good as all your code adjust automatically be updated so another thing that people should know is right now Google is using rxjs 6 in production the same bit that we're talking about and we also ran these same TS lint rolls across thousands of files inside of Google and updated everything and it's all it's all working so all of this has been thoroughly tested for you by Google because we've only got one version of rxjs inside of Google and it's it's rxjs version 6 right now so proceed with confidence that this stuff is going to work so just a summary you want to use the new pikeville operators in version 5.5 if you're not already version 6 what it gives you is simplified imports you got reduced api service api surface area and it fixes this unhandled errors problem this producer interference problem that's really nasty and then the migration process the first thing you want to do again is update to 5/5 first and make sure that you've got all of your bugs fixed from that and then you install ArcGIS at our C or the latest version of rxjs rxjs compat will make all of your not compatible code that it's backwards compatibility so to make your code compatible again and then you can run the TS lint rules to help you migrate and then remove those that compat package and last a little bit this bonus this last thing I'm going to tell you is there is the super secret version 7 work is now public there's actually it's based off of Andre Stahl it's my friend Andre salts call bags and we're gonna have the same public API obviously - things that we are we're telling you we're deprecating but it's gonna have the same safety guarantees and it's much much much smaller and faster an order of magnitude in some cases for some operators it's there's an experimental branch at this link that you can go check out as far as like seeing what it looks like and there's an active design documents about ten pages long discussing like the whys in the house of this and I say active because vacation I'll go through and delete like a whole paragraph and rewrite it but just if you're curious it's it's out there so it's it's not hidden from anybody that's it thank you very much [Applause]
Info
Channel: ng-conf
Views: 36,439
Rating: 4.9347472 out of 5
Keywords:
Id: JCXZhe6KsxQ
Channel Id: undefined
Length: 23min 51sec (1431 seconds)
Published: Fri Apr 20 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.