Here I'll talk about how responsive programming (reactive programming) pushes asynchronous programming to a whole new level.
Asynchronous programming is really hard.
Most of the speeches and articles on responsive programming are showing how amazing the reactive framework is, giving some examples that can be done in very complex situations with just a few lines of code. An example? I have a code for a rxswift-based chat program here:
Socket.rx_event . Filter ({$0.event = = "Newmessage" && $0.items?). Count > 0}) . Map ({Array ($0.items!)}) . Subscribenext {data in let username = data[0]["username"] as? String?? "Unknown" let text = data[0]["message"] as? String?? "Invalid text" let message = Jsqmessage (Senderid:username, Displayname:username, Text:text) self.messages + = [ Message] self.finishsendingmessage () }.adddisposableto (disposebag)
This code shows how the socket event is filtered and processed to show messages sent by a particular user in the chat.
The classic method may end up with code similar to the following:
Dispatch_async (Dispatch_get_global_queue ()) {let socketdata = Self.loaddatafromsocket () let data = Self.parsedata (data) Dispatch_async (Dispatch_get_main_queue ()) {let username = data[0]["username"] as? String?? "Unknown" let text = data[0]["message"] as? String?? "Invalid text" let message = Jsqmessage (Senderid:username, Displayname:username, Text:text) self.messages + = [ Message] self.finishsendingmessage () } }
This is called "Callback Hell" and the code is difficult to read and maintain. But apart from being really hard to read, why is the callback so bad?
Synchronization becomes painful
Synchronous programming is not just about running a task in a separate thread or performing calculations, at some point we need to synchronize the values in multiple threads, and the most common workaround is to add locks. Once a lock is introduced, the complexity of the code increases by at least an order of magnitude, and introduces a new problem: unpredictability.
In terms of computation, the code now becomes unpredictable. When a single thread is dispatched, and if we access an expected single (locked) attribute value, there is no way to know for sure whether we will lose the value or are processing the same value as before.
So what is the real difficulty of asynchronous programming? The answer is sync. It sounds interesting, but it's true.
Getting started with the responsive approach
It is important that responsive programming is not a young concept as many of us think. Its origins date back to the 1969, when computer science legend Alan Kay, a doctoral dissertation at the University of Utah, was named "the reactive Engine". But I'm not here to give you a history lesson, considering that some of the concepts sound good and the experiment doesn't work so well, so let's look at the value of responsive programming when it comes to synchronizing code.
In the RX world, the most fundamental part is the combination of the Observer pattern (Observer pattern) and the iterator pattern (Iterator pattern), both of which are well-known patterns, and are widely used to handle specific behaviors when writing software. The observer pattern and the iterator pattern, which are mutually interacting, are computed in both cases by the values taken from the producer. For the iterator pattern, as long as they are available, we can get the value, and for the observer pattern, we get the data to process the value after the producer notifies all the specific observers. Getting is definitely a good, specific solution, as long as everything is handled in the same thread and it works well. What happens when the data is fetched and processed one step at a time? Okay, now that the lock we've added is starting to work, things are going to get pretty fast.
Imagine scenario
We envision a very good application that is ready to be released within a few days, but in the final test, in some cases, some deadlock and requisition conditions have been generated, and the application crashes are random, and only enough data is available to determine the problem. Time is limited, and problems can occur more quickly than expected, but solutions may not be developed and deployed as easily and quickly. The first thing to remember is that once a locking strategy is adopted, the entire code slows down and the unpredictability of asynchronous programming affects the performance of the general application. There may also be an order of magnitude slowdown, and we can get the conclusion that this is unacceptable.
What is the response type
The response is a design, the acquisition of data is an absolute thing, it may be difficult to adjust in a short period of time, so a solution is to flip the behavior, that is, why can't let the resources to push the value to a user/consumer, but we go from a resource to get it? This is the RX specific content that pushes the data to the instance that the producer subscribes to. We generate data in some places and then push the data to the user and process it as needed.
Observer + iterator + push = observable (Observable) entity
The math behind Rx is simple, and two very deterministic entities, combined with different interaction models, form the foundation of an observable entity. This is where the revolution takes place, combining old, established concepts to create and simulate a powerful abstraction in a way that helps deal with asynchronous programming without risking the project hanging out in the last week.
The result of this mathematical formula is an entity called observable that handles the raw data and pushes the value to the user, if necessary. Users can play multiple roles, and they can be other interlocking observable entities, operators, or just callbacks. Rx is very basic, but also very powerful abstract concept.
Statement
The method of using observable entities requires declaring logic when an observable entity is initialized, which means that our code becomes more compact and is often limited to the initialization method of the view controller. In this example of Rxchat, most of the logic is declared in the function of Viewdidload:
Override Func Viewdidload () { super.viewdidload () //Do any additional setup after loading the view, typically fro M a nib. Self.setup () user . distinctuntilchanged () . Subscribenext () {username in Self.senderid = Username self.senderdisplayname = Username self.socket.emit ("AddUser", Withitems:[username]) }. Adddisposableto (disposebag) socket.rx_event . Filter ({$0.event = = "Connect"}) . Map ({_ In return ()}) C13/>.subscribenext {_ in Self.title = "Rxchat (Connected)" }.adddisposableto (disposebag) //[...] }
This approach, also known as declarative programming (declarative programming), helps us effectively reduce the number of potential bugs and makes the code written when using MVVM or similar patterns a bright one.
What do we do now?
In general, learning Rx or responsive programming is like learning a new language (not a programming language), the steps are very similar, we learn the basic grammar and common sentences in the initial stage, then learn the rules and semantics, finally we can say some even the most difficult topic, we mastered the language.
In order to continue learning, I suggest that readers read the following information:
- Reactivex
- Rxmarin
- Reactive SWIFT-MY journey with reactive programming in Swift?and The IOS app that came out of it
- Climbing the Reactive learning Curve
Summarize
This article may seem very short (in fact, I'm going to write it so short), but it writes out the basics of Rx in my mind. Most of the articles and speeches are discussed at the periphery on how to use it, why use it, but few people discuss why RX is so powerful and why it can be so short. There is no magic under the RX's Mask, and Rxswift uses something that is existing, it just builds the concept, and uses it in a clever way to glue these things together to create an abstract concept of powerful asynchronous computing. Don't take the time to write synchronization strategies for your asynchronous software, just spend your time writing logic.
Reprinted from: Http://www.infoq.com/cn/articles/swift-responsive-programming-revolution?utm_campaign=rightbar_v2&utm_ Source=infoq&utm_medium=articles_link&utm_content=link_text
Brief analysis of Swift responsive programming