Christina Lee: Intro to RxJava

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so hi my name is Christina and I'm here to talk to you about intro to rx just a caveat before we dive in I think a lot of intro presentations are of the form here's this thing it's really easy use this one or two lines in your life is better and I really really wish I could give that presentation I would love to give that presentation unfortunately Rx isn't something where that's possible to do Rx is complex and it's intriguing and it's fun it's anything but simple in a lot of respects so bear with me there's a lot of content we might fly through it I'm going to do my best to make it understandable but it's not going to be simple it's not going to be one line and I hope that's alright alright before we dive into what Rx is let's take a look at the current landscape because if there's no problem you don't need a solution so background to things that interest us here today why do we need asynchronous work and what is the state of that work on Android right now well the first question is really easy to answer it's because users are our friends and we care about them and we want them to have a good experience if you use asynchronous work you can leverage the power of servers and other really complicated back-end processes that can do things that you can't do if you're just limited to your mobile device and you can deliver awesome experiences to your users without slowing them down freezing the main thread or giving them J key performance as to the second point there are a lot of tools for you to use this is by no means a comprehensive listing it barely scratches the surface of all the different things you could use to address asynchronous concerns on Android but there's some of the most popular ones I'm sure a lot of you have heard of async task and probably use it but there's also futures event buses and of course observables which we're going to talk about today because this isn't comprehensive I've linked to a more info blog if you want to go check that out after the talk it goes through everything on Swift and Android or almost everything and and I do want to caveat that when I say features here I will use future is in the canonical sense by just saying futures I do not mean the built-in futures I mean listenable futures there is a lot wrong with the built-in version of futures that can really trip you up so here I'm using futures to represent listenable futures which which use features under the surface but add a lot of nice functionality to it okay so we have a lot of tools and because we have a lot of tools and we're only going to end up using one or maybe two we need a way to evaluate those tools and I'm not going to stand here and say that I have the answer for what the best evaluation metrics are but I'm going to offer my perspective on it and three of the things that I think about are when they run how they run in whom they affect and when I look at these three three things it really gives me some perspective on what tool I should use so if we look at a sink as an example you can notice that async tasks need to be executed explicitly and this is awesome because it means that we have control of when it starts the work can't easily be modified in a sink test though so in terms of how they run you kind of kick it off and if you do want to compose things you can get into a couple levels of callbacks it's not ideal it's kind of hard to bring things together and in terms of output a lot of the data is very side-effect II and if you're not familiar with the term side effect one awesome concept I would encourage you to go look it up but - it's very it has a corollary to what we use in the medical sense so if I go and take a cold medicine the goal of that medication is to cure me of my cold if it turns me green that's a side effect that was not the goal I don't want to be green and similarly here if you try to do something and then it reads from the network or a hit state and that's non-deterministic that's considered a side effect because you can't always know exactly what's going to happen based on your function signature and the like if we look at the code for this you can see that bottom line that's where we're executing this explicitly you can see that there's a doing background there where we kick something off and then once that finishes running we get that callback in the on post execute but it's not quite sure how you would compose things from there change them once you kick it off okay if we have evaluation metrics we should probably have some ideals that we're shooting for because otherwise what's the point of having metrics so I'm going to offer some ideals which I think we should shoot for first explicit execution if you can start something you can control it this is not always true with futures wherein if you just create them they're running you want to have as much control as possible I think in this case not always it can you know with great power comes great responsibility in this case it will help you because you can create them and you can you can play with them before they ever kick off you also want easy thread management this is a talk about asynchronous behavior thread management is key you want it to be easy and then you want them to be easily transferable and as few side effects as possible I'm going to dive into each of these but the basics are the same so again explicit execution it means that you can play around with these observables you can create them and store them and modify them and right when you get them perfect right when they have all of the data that you need they look exactly the way you need you can kick them off and not a moment before again in terms of threads management this is asynchronous work if you can't easily switch threads or understand which thread you're on that's bad because you're probably going to make mistakes because of that so we want that to be easy because it's readable and because it's better for you as a coder in terms of easily composable it would be great if asynchronous work was one and done we kick something off network requests it relies on nothing we don't need to do anything when it comes back we just do it and forget about it and great but the world doesn't work that way and often things are interdependent and if they're interdependent you want to be able to play nicely together if you hit the cache and then the network you don't want to have intermediate steps there you want to be able to chain those together in a way that makes sense so if you're a synchronous library is easily composable it'll introduce less room for error and that's a good thing that's a win for us and lastly minimizing side effects the fewer side effects you have the more easily you can reason about your code the more easily you can read it and you bring someone on to understand it as well because it doesn't depend on state it's deterministic and it's just much easier to talk about alright I set these standards you probably know where this is going I personally think that Rx meets a lot of these and I'm going to tell you why so Rx is explicitly started you have to subscribe to it if you want anything to happen and before that time you're still building or creating or storing and things aren't kicked off yet it is very easy with rx to understand which thread you are on because there are single line operators subscribe on and observe on where you can assign the thread and so if you're reading code you see can observe on IO thread you know that's happening on the IO thread they're easy to transform and to filter and to map and to do all sorts of other operations on this is where they really shy and they're also really good at minimizing side effects this is asynchronous work so they're never going to get rid of them you're hitting the network you're doing a very state bound stuff by definition but they do a really good job of minimizing that so fast facts about rx1r X is for asynchronous events it's for composing them in particular to our X stands for reactive extensions and three our X comes in a lot of different flavors so I'm giving a talk today in the context of Android for rx Travie but you can do this in JavaScript you can do this in Swift you can do this in many different flavors the three key points of our X are the ones that are on screen now Rx has observables it has linked queries and it has schedulers and I say linked queries it's based on these it's based on these concepts even though it doesn't explicitly use them so between the observables and the queries and the schedulers we get the world that is rx to dive in their observables represent asynchronous data streams and this is usually a part that's hard for people to understand when they first come to rx so I'm going to really dive into that later but for now just assume that there's rheems queries allow you to to compose those streams with operators and schedulers unsurprisingly allow you to manage concurrency within those streams so to review these are the three core parts of our X we can represent asynchronous data streams we can query and combine those streams with operators and we can manage the concurrency of those streams with schedulers so to jump in to the first piece of that observables observables like I said are streams of data there pull based with the caveat that you can use some more advanced features and rx to do some push based stuff but in general their pull based and you can create store them pass them around etc because they are explicitly executed and that last point is what I really really want to drive home observables are here because they help us hide away all of the complexity that can come up with reading and synchronization it's not that that complexity is gone it's that this library will handle it for you and we hope that they'll handle it better because that's their full-time job Rx is usually very difficult solely or not solely but primarily because of the concept of streams and of observables so I was talking to some people last night asked them how they thought about streams how it finally clicked for them and someone said the factory analogy was what really made this make sense so I'm going to throw this out here hopefully it'll help some people if not just think of them as streams but hopefully this will help so the factory analogy says that you start with some raw material maybe you're making cars so you have steel come into your factory and this is the raw material this is our network request we're starting somewhere and then once you have that raw material you send it down a couple of conveyor belts you might pound it into sheet metal or shape it into the the car's body or do something like that and you also might introduce some other resources from a different factory maybe you need rubber to make tires and as you progress down all of these conveyor belts you shape it and you add to it and eventually when this car gets pushed out the or you have your final product which in our case is where we get the data out of the stream so we put something in some raw material we shape it in many different ways and then at the end we get the product that we want all right two key phases of the observable lifecycle I still call it although that's kind of a pseudo comparison is you want to put data into them and you want to get data out why else would you have a stream this is for data so looking at that first part putting data in there are a lot of different ways that you can do that and I'll show you a few of them the simplest is by saying observable dot just here is a string I only want this so I'm just going to put that thing in the second you can use observables with iterables so if you have an array say I've made an array here of me and some of my friends names Christina Nicole and Alison I can say observable from this iterable and what would come out of that observable is Christina Nicole Alison and then it's done the most heavyweight of any of the creations is using dot create and you'll see here that what happens is I get some subscription s and I'm particularly managing what's being sent down in this case I say subscription send it on next with this string I created an observable and then I don't want to put any more strings in there so let's just tell you that your completed so then I say subscription your complete and this isn't observable right here nothing has yet happen but I've built one and the behavior of it would be it emits the string and then it completes itself you might notice that that was not in Java I have the Java translation below and if your face is looking a little bit like this right now I just want to explain why I made that choice I'm I could not frankly fit the Java interpretation on each slide because rx has some different functions that you have to pass it and so something like this is a lot smaller than something like this or you'll see later on even farther than that and so I hope that you think of this in terms of pseudocode this is actually written in Kotlin some of you may have heard about it you don't need to know anything about Kotlin to understand how our ex works so if you think about this as pseudocode that's a lambda there I know people are using retro lambda a lot hopefully this isn't the first time you've seen it but if it is what this function signature says is that I have input to my function s and I'm going to do these two things to it and so I'll use this a lot it's okay if you still look like this I do apologize but I just wanted to let you know as we go through this slide I will be using Kotlin just so I can fit it on the slide but I'm going to try to explain as much as possible so we avoid as many of these moments as we can now that said this face may not have been made only because I was using Kotlin there is also that uncomplete there and that's a little bit crazy because we were doing all of these on necks and we were using arrays and all of a sudden there's on complete and what is complete even mean that's like not even a putting data in thing that's a getting data out thing and you're right so this is a really opportune time to switch over to the getting data out part of observables because without understanding how you receive data on the other end of a stream it's really hard to understand how you should put data into the stream and to that end remember these are streams it's very important for this next slide so what do we need from a stream well primarily we want data we want a way to say hey what's the next piece of data I hit the network what did I get back we also want to know is there anything left to do because if they're not I'm done I'm going to move on I'm going to recycle my assets so we really want to be able to know hey should I still care about this stream or can I move on and lastly because the world is not perfect the bane of our existence did any errors happen that I should know about what does that look like in code well this is great I hope you enjoyed this as much as I do when I want something you know the next value I can call on next when I want to know if something's completed I can call on complete and when I want to know if something's alright alright guess for it there we go so hopefully these names make a lot of sense they're very readable it's one of my favorite parts about rx nothing should surprise you here next value on next completion on complete error on error so this is pretty easy to keep track of one of the the better traits what does this look like in practice well again we have that top level function create so we're saying observable create in this instance I've typed it with string so this would be an observable that emitted a bunch of different strings you can you know put a different type signature in there and then again reading this Kotlin as if it's pseudocode we have some subscription and we say all right I have a function that's very expensive maybe it's reading from disk or something let me go ahead and do that and get the value back and once I have that value let me put it on to that stream by calling on next so we we call the function get a value and we say s dot on next that value and maybe I'm not done maybe now I want to hit the network or I want to do another disk read or who knows what there's some other expensive function again so I'll call that and then I'll get the value and I can push that on the stream as well using on next again and maybe I only have those two expensive things maybe I have more in this case we're done after those two calls so then I'll tell the stream it's complete and I'll say I'm complete to go into each of those steps a little bit more you can call on next as little or as often as you want now I have an asterisk on the screen because it's not entirely a truthful statement and to that end I've linked below to some perf issues that you can encounter if you do this too much for an intro to rx talk you probably will not run into that but it's something to note that if you're doing really heavy processing you could run into some perf things and you want to be careful with this and handle them correctly pop quiz with on next I really this is key and I really want to make sure people get it so can anybody tell me what this stream looks like what would the output be it's not a trick question it's really as easy as you think it is two or three exactly that's it it just puts two puts three and then it's done similarly output for this it's going to look like apple banana orange pineapple and I'm done and to really drive this point home you can do this as well you can just build up some binary numbers it's going to look exactly the same you're going to output those one by one and then the stream is going to close so I feel like there's a lot of mysteriousness around on Macs it really is just that simple moving on to on error it's really key this one point that I'm about to make if there's one thing that you take away from this I hope that it's this because it'll save you a lot of trouble on error and on complete both end streams they are both terminal events for streams the only difference between them is that when you call on error the stream is ending because something went wrong and when you call on complete the stream is ending because you finished your work there's nothing to do move along but the both end the stream and the only difference is why the stream is ending so another I'm going to go into that a little more in the next slide but just another point one great thing about on error in rx is that all errors are handled in a single place so you can combine a bunch of different observables any error that happens will be surfaced in your on error so if it happens far upstream if it happens downstream it'll all come to you in the form of the on error and this is different from things like futures which have individual success and failure callbacks and then maybe you need to tell another feature about this futures error so how do you propagate this and blah blah this propagates down to the lowest level all errors are here if you find an error it'll be here look here if you want errors that's that's the gist of it returning to that first point about terminal events here's an example that I want to walk through to just drive home this point so we have unobservable we've created it we put some try-catch in there because there's a function that might error I don't know what that's doing maybe it's hitting the network but it could error so in the case that we assume that that function succeeds we call it we have an on next it does hit the catch and then we do on complete so that output it calls on next with whatever value that was and then it calls on complete but this is not the case if that function error so this is exactly the same observable creation as before but this time let's assume that function that might error actually does error you might expect that it would call on next and then on complete or on error and then on complete but remember on error is a terminal event for streams so what you actually get is on error that's something that's probably unexpected so take a moment let it sink in after on error that stream is complete there's there's nothing to call on complete for because that's the successful stream ending we've already ended it in a non successful way okay on complete we've kind of bashed over it up until now it really is what you think it is it tells you that the stream is done go ahead and clean up after yourself recycle anything that you're holding on to and basically just move on so review we have our on next we have our on complete and we have on error and each of those do hopefully what you would expect them to do propagating the next piece of data telling you that a stream is complete or telling you that some part of that stream had an error and here it is oh yeah you thought this was going to be hard three steps that's it rx all right unfortunately there's more so if you remember when I talked about link queries the key point there is that the thing that really distinguishes observables from a lot of different approaches to asynchronous work is that they really really shine in terms of being able to compose them and transform them in different ways that you need to in your code and so we're going to dive into operators right now there are so many operators I couldn't even begin to tell you all of them you love operators for filtering and for you know taking a few and then skipping a few and for mapping and for flat mapping and for anything that you could imagine their operators for that what do they look like in practice well if you look at this screen the observable dot from of an array is exactly what we saw earlier in the presentation if we had that observable on its own it would emit one two three and four and then it would cease it would call its own complete here though we're adding one extra step which is a map and so this map it has a variable that comes in so the function is given some variable called number and what we want to do is we want to say return number plus one so one will come down and we'll have one and we'll say but we don't want one anymore we want one plus one so two will be emitted and then two will come down the stream and we'll have two plus one so three and so all of a sudden an observable that used to emit one two three and four now emit two three four five all right we can also do filter another easy example here we have the number and we return a boolean expression which is if this number mod 2 is equal to zero then pass it on if it's not then that doesn't get emitted on the stream so here 1 mod 2 is 1 so it's not going to get passed on to mod 2 is 0 so it will so our output goes 1 2 3 4 and after the filter becomes 2 & 4 this is just to give me evens number function we can also do things like combining and merging observables so all right I don't have that many friends they all fit on a slide so you can see the first one my school friends I have Moe and Dave they're great then I have some work friends I have Nicole and Allison so there's an observable for them too and then at the bottom I combine all my friends so I have alright let me create an observable from the merged output of my school friends and of my work friends and this output looks like this we have Moe we have Dave we have Nicole we have Alison and then it's done all the elements of both observables are represented in this output and then we complete because there's nothing left to process now I left a note here for you the reason these are in order is because you know it's just an observable with names that are string so it's synchronous if you were doing network stuff it's perfectly valid for it to be nicole mode and then Alison they don't have to be ordered like that okay because I cannot cover the rest of them that was only three examples I'm going to point you to rx marbles people have a love/hate relationship to it I personally think it's great they have visual representations of what operators do so I would encourage you to click through there this is a link on the slide so if you are looking at these slides later you can just click through and it will take you straight there alright moving on to that last part the schedulers this is where it gets fun because we are talking about asynchronous work if you do not subscribe nothing happens and again you can see that asterisk because I'm sort of lying to you there's this caveat here advanced performance stuff you'd probably don't need to know about it right now but they're a little bit of considerations for for this if you are doing something that really that matters for it but in our context and intro to Java context if you do not subscribe nothing happens so all of those slides in the past I was saying observable create thing then I put output that was not totally true that was the output that those observables would emit but they did not actually emit it because I never said subscribe on them I just created an object that if you were to subscribe to it would have emitted those things so something about subscribers they can take a different number of functions they can take no functions if you just want to kick off that work and you don't care about what it returns they can take three functions if you want to give it on next on complete and on error so maximum of three minimum of zero I'm going to stand up here and really strongly suggest that you always pass at least an on error because if you don't your stock trace is going to be completely unreadable and you're really going to hate yourself so please at least pass it on error to it it's really important if anything goes wrong for you to be able to understand what went wrong and then in terms of saying where work should execute we have these two different operators that we can use which are subscribe on and observe on and I'm going to go into those later but just know that that's how we're going to manage where work is run what does this look like in code well again not shockingly I have an array with the same names as always say observable dot from this array and then that last line is what's new I say dot subscribe and then in this case I'm passing it only one function I'm passing it on next function and that line there just says next piece of data I get print it out that's it so the output looks like this it prints the names and then nothing else happens now if we want to be more rigorous we can pass all three functions so this is a full function suite we pass it on next which is that first function there we pass it on error log the error and then that last one is on complete and will log on complete so this output should look familiar we've added one line here though which is it does the on next as it used to but now we've added it on complete so when the completion event happens we have a print so there's that extra print at the bottom that says uncompleted alright what I have thus far ignored is that dot SUBSCRIBE will return a subscription you may not need to use that subscription but it should shock no one that if you have reference to a subscription you can call unsubscribe on it and that looks a little something like this I call subscribe on some observable let's say it's the one that I created on the last slide and then I print something that happens in on next so again it would just print out names or something and then if I don't care about that work and I actually don't want to listen for it anymore I can just call unsubscribe because I have the reference to this subscription so you don't need the reference but it's really good in terms of cleaning up after yourself if you keep hold of it when you subscribe on something so this is the meat of observables and of schedulers and of all the subscription processes what about the threads where is my work running so again to recap we have these two operators that we can use to tell observables where they should be doing work subscribe on should only be used once you can add it more than once it's not going to matter the subscribe on that happens closest to the point at which you create your observable is going to take precedent so if you call subscribe on in the first right on main thread and then ten lines down you call it on the i/o thread it will subscribe on the main thread it's going to ignore anything downstream of that you should use it once and that's it it defaults also to the thread if you do not explicitly stay where it should subscribe on it defaults to the thread where you create the observable oftentimes this is main thread but if you create an observable on a computation threat of some sort you should probably put a subscribe on to make sure it's actually running where you want because it will default to the computation thread as the place where it runs and then the key point about subscribe on is that that first block of code is always going to be executed on your subscribe on at the point at which you subscribe code will start running on that thread so maybe down the line you're doing other stuff and you want to change the thread with an observe on that's fine but subscribe on tells you where your code starts executing that very first block will always run on subscribe on until you get a chance to change it if you so choose that leads us to observe on maybe you've subscribed on one thread maybe it's a computation thread but now you want to surface something and put it in the UI so you want to switch back to the main thread that's where observe on comes in handy you can use this as many times as needed there's a dreaded caveat again there's some back pressure issues again if you're not doing really really performant required things you probably won't run into this but if you are it's in the notes and it is important to understand with observe on it affects everything downstream so if I put an observable on line 2 of a 10 line observable chain it will affect lines 3 through 10 unless I put another observable on line 6 or observe on on line 6 in which case that observable now will affect everything downstream of that so everything below your observe on will happen on whatever thread you tell it to observe on and we can look at that in code I'm going to build this up line by line so I splash it on screen everybody's going to run out the back door screaming so this is going to go line by line so we start with an observable you've seen this a million times at this point it's just going to emit a bunch of colors that's it now I'm going to add a do on next you haven't seen this yet but do our next is somewhat self-explanatory when on next wire I'm going to do this function that I provide in this case the function that I provide is just a log I just wanted to print out what thread it's occurring on so that's all that's going on there print the thread when all next happens now maybe something else needs to happen and I don't want it to be on the thread any that thread anymore so I put an observe on and I say all right let's switch our thread over to i/o and then I want to do something like map it I have a string of colors maybe I only care about the length of the string that's what's important so I'll say all right take this string and then instead of having the string give me back the strings length instead and then you get the full finished product I add that subscribe it prints out the thread that I'm finally getting my output on so what is this output look like well it starts on the main thread because I didn't give it a subscribe on and I wrote this observable on the main thread in my sample app and then after I switch over to the i/o thread unsurprisingly it starts submitting things on the i/o thread so you can see in those bottom three lines it says that we're on the i/o scheduler now let's say I want to use this explicit subscribe on I don't want this to be run on the main thread this is exactly the same observable we just built up line by line but there's a subscribe on call there and I put it on the computation thread how does that change things well now you can see that that very first work that was done it was done on the computation scheduler and after that once we switch over to the i/o thread and we map it to the length that's happening on the i/o scheduler and so this is one of those examples where you can see that we can start work in one place we can switch over to a different scheduler and it can be done elsewhere I could also add a different observe on to put it on main thread and it would just you would see that ripple through the output as well all right rxi mandroid I haven't talked about Android at all I've just been going through observables and rx Java in general let's talk about how this can impact your life as Android developers so again this is just like operators I can't tell you all the ways you can use rx Java in your app because the sky is the limit whether you should be using them in places is a totally different question but you can use it in many different places here's just a few somewhat contrived examples you can bind clicks and then filter for a certain quadrant or you can see if people double tapped by using a you know kind of an aggregator on your observable given a time frame you can flat map cache hits with the network you can handle off flows in a single stream so you get user input and you send it to the network and then you get a response back maybe hit the network a second time fetch user details all of that can happen in a single stream and I'm going to walk through a few examples but before I do just want to say they're here to give you flavor on what this can look like in an android app if you don't understand all of them that's okay the idea here is to just get a notion of what is possible so here's an example of D bouncing a button I'm not sure why you would need to do this but you can do it and and so what's happening here is I'm just adding something to a button class called D bounce I can give it some unit of time and then I can start with saying set unable to false I'll set a timer observable it'll fire when it fires I said enable to true so obviously in the time that set enabled is false users won't be able to click on this button and then after my time is elapsed and on next has been called and enabled false as turn to true then users will be able to click again you can do things like I used to work for a photo sharing app and we had a bunch of photos stored in our RDP so one case that we use this is a pair down example of it is I would get my database with the context I would say hey load up some photo details for me I really care about the most recent one so so can you order those by timestamp for me and then oh by the way I can't deal with that many at once so just give me like the last 24 that's all I really care about and then maybe all I care about is the size of those photos I want to do something with the UI who knows so then that last line just says hey instead of photo details just give me the size of the photo map it to its size and this may look very dense it is if you try to do this without Exce you would like this would be a five-page slide this would just go on and on I would be flipping forever and so the fact that you can do this in six lines is incredible this is really complicated stuff and it's pretty readable you can do the canonical example of I oh you can maybe download something we have some function that writes an output file I don't know what's going on there but we get a file back maybe we check the type if it's a photo put it somewhere if it's a video put it somewhere else if it's none of those then what is going on here throw in an error and then we in this case right here we're not sending data through the stream because we don't care what we're using this observable from is like that toast that comes up and says download completed or download failed so we don't actually need to send that file down the stream because we have no use for it all we care about is did this complete or did it fail so you'll notice there that we have the on error if it errors if we don't know what type of file we don't know what to do with it and if not we just spire on next with no argument unit is the null type here so it's just saying fire on next that I'm not going to give you any argument to your on next function it's just going to exist and then we say all right we're complete here wrap it up you can see also there's a subscribe on IO so you can put a subscribe on there's also ways to lift things from local broadcasts so this is an example of one of the things all of those apps that give you codes they text you codes and then you have to input them into your app and that's how you off you know Android is great because you can scare people by just reading their text messages that's fun and this is an example of that happening so someone sends you a code you Auto read their text message pull that code out and get it in a local broadcast but local broadcast can be a little bit clumsy so let's go ahead and transform that into an observable so what's happening here is we have the intent filter to get the verification code and we give that to a content observable dot from local broadcast and then we don't actually need the intent here that's not what we're interested in what we really care about is just that verification code so I can make sure it's the right one so that last line just says you gave me an intent but really all I care about is the verification code so pull that out of that dictionary and you can see that the return type is a string question mark that just means that string could exist or it could be known so if that key doesn't exist in my intent it's just going to return a null if it does exist it's going to return the code and I can do further checking you can also build up really complex onboarding flows this is pared down in sort of pseudocode but a time doth observable is kind of that situation that you run into where you input your credentials and it's seeing if they're valid so you see the spinner but then maybe you're in bad network so it will come up with like connection failed then you hate yourself so lots of time to auth observable and then you can put that on the IO thread because you're hitting the network then maybe you want to do things downstream what this is it's not important I've kind of added some pseudocode like you want to verify your response then now that you're logged in you want to get a suggestive username so they can finish onboarding with their suggested username so what's going on here is less important than how it's going on which is that your entire off flow is now in these eight lines of code and you're managing where that code is running very easily by using observe on and subscribe on you can also do things like this you can if you're not off kick off an i/o event to get off and then once you're off you can then call a function now that you're off that hits an author response this is not easy to do without observables because you have something that's getting the authentication and then you store that and then you kick off this totally separate task that does the result for you here it doesn't matter that you're uh nought to start because by the time you get to that flat map user service off client you are off because that's the waste streams work you go from the top of the stream to the bottom so that by the time that function gets hit you're off or an error with strong and you'll you'll know that the air is thrown so this is really powerful it may not look like much but you can start out as a not logged in user and you can compose that with logged in stuff downstream after your i/o all right that was a lot let's summarize you guys still with me okay I'm not here to tell you that Rx is the only game in town or that it's always the right solution as you've seen in this presentation there's a lot of things that are non-trivial about it and that can be confusing so that's not my point but my point here is that Rx is one of the most powerful games in town so while it may not be right for everything if you're doing really high performance stuff if you're doing stuff where you hit the network or you're reading from disk a lot or you're doing a lot of asynchronous work it really can be the right tool for the job it's heavy weight but that comes with a lot of benefits which is that it can do a lot of stuff there's a steep learning curve I get that it sucks it's like walking on glass as we were talking about last night it's unpleasant but once you master it it can really help you reduce errors so once you learn to think in this way things become a lot easier to read because they're mapped together in a logical chain of events you can see that something hits the network gets transformed and then it's put on the UI thread to be used by your UI and you can see that all in one place it's not going off and disappearing somewhere you're not storing it in state it's all in a chain that chain represents an entire action and you are introducing extra opportunities for errors by using stateful storage and then lastly I get that streams can be a huge paradigm shift we don't think like this often because it's just not how most apps are built but if you can switch over to thinking of data ash streams your entire apps data flow can be brought to the surface so right now when you're using other async primitives what can happen is you send something off to a thread here and then maybe there's a thread here and then this activity is doing something and I mean who knows you can have asynchronous stuff going on in a bunch of different places what happens if you use is you use threads is that it forces those to be connected and so you can easily write a GUI and these actually already exist where you kick off a network of it and you can see exactly where it flows through your app all the way to the point that you stick it in your UI or put it somewhere else to be used later so the first call to the network the transformations when you're bringing in other data or filtering data or reducing data all of that can be surfaced in a GUI and that's powerful because it gives you a way to talk about your app that everybody can understand if you have a roadmap you know where you're going and that's really really useful not just for developers but for product people to tell them how the pipeline works where you're getting your data how it's changing and where it ends up so lastly this is the best summary that I can give you about Rx if you have a car if you have some old clunker of a car and all you're doing is going to the store that's absolutely fine the streets are what 25 mile per hour speed limits you can make that and like yeah maybe the seats not so comfortable but you can adjust to fix that and just kind of get comfy over in the corner and maybe you know it doesn't start up and cut have to jiggle the key but that's fine it works and you get there and it's great however if you have to go cruising for for road trips or you're getting out on the freeway I guarantee that if you bring a Tesla and you bring an old car you will notice the difference because the power is there the safety is there they've learned a lot in the last 20 years about driving so that Tesla I mean have you seen its safety record it's world renowned and that's because they've watched what's happened before they've corrected for those mistakes and they've built it into new technology so yeah if you're going to the store with your Tesla you probably won't notice that much of a difference because 25 miles per hour is not what that car is built for you don't need to go 0 to 60 to get to the grocery store it may not be your best option but if you were yeah yeah right like the feeling out in the the parking lot you're going to get arrested real quick but if you were driving across the country if you are doing something bigger something more complicated something longer-lasting if you were doing something more monumental the Tesla is what you want it fits that use case it'll make your life more enjoyable you'll be safer doing it and it's just going to be quite frankly a lot more fun so I'm going to point you to a few more sources I know I couldn't cover everything there's RF marbles and other documentation dan Liu also has a great series of blog posts on this topic he's here so you can also bug him in person if you want I'm going to throw them under the bus here I think that they're really easy to understand they were helpful to me when I was getting started also the slides are live okay again caveat they will be live as soon as I walk out of this room I put as you saw through this presentation a lot of documentation under the fold so every one of those Kotlin functions that I wrote has a Java translation below the fold so if you press the down arrow on any one of these slides you'll find links to more resources and the translation and the output and anything else that you want in reference to that slide also I'm online if you want to yell at me or ask me questions or any of that sort of thing you can find me at twitter on twitter at run kristina run and that's all guys thank you
Info
Channel: Realm
Views: 29,883
Rating: 4.8379374 out of 5
Keywords:
Id: XLH2v9deew0
Channel Id: undefined
Length: 45min 21sec (2721 seconds)
Published: Tue Oct 25 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.