【轉載】ReactiveX 的理念和特點

来源:http://www.cnblogs.com/why168888/archive/2016/10/19/5976506.html
-Advertisement-
Play Games

ReactiveX是Reactive Extensions的縮寫,一般簡寫為Rx,最初是LINQ的一個擴展,由微軟的架構師Erik Meijer領導的團隊開發,在2012年11月開源,Rx是一個編程模型,目標是提供一致的編程介面,幫助開發者更方便的處理非同步數據流,Rx庫支持.NET、JavaScri ...


 

原作者地址:http://www.open-open.com/lib/view/open1440166491833.html

 

ReactiveX是Reactive Extensions的縮寫,一般簡寫為Rx,最初是LINQ的一個擴展,由微軟的架構師Erik Meijer領導的團隊開發,在2012年11月開源,Rx是一個編程模型,目標是提供一致的編程介面,幫助開發者更方便的處理非同步數據流,Rx庫支持.NET、JavaScript和C++,Rx近幾年越來越流行了,現在已經支持幾乎全部的流行編程語言了,Rx的大部分語言庫由ReactiveX這個組織負責維護,比較流行的有RxJava/RxJS/Rx.NET,社區網站是 http://reactivex.io/

什麼是ReactiveX

微軟給的定義是,Rx是一個函數庫,讓開發者可以利用可觀察序列和LINQ風格查詢操作符來編寫非同步和基於事件的程式,使用Rx,開發者可以用Observables表示非同步數據流,用LINQ操作符查詢非同步數據流, 用Schedulers參數化非同步數據流的併發處理,Rx可以這樣定義:Rx = Observables + LINQ + Schedulers。

ReactiveX.io給的定義是,Rx是一個使用可觀察數據流進行非同步編程的編程介面,ReactiveX結合了觀察者模式迭代器模式函數式編程的精華。

ReactiveX的應用

很多公司都在使用ReactiveX,例如Microsoft、Netflix、Github、Trello、SoundCloud。

ReactiveX宣言

ReactiveX不僅僅是一個編程介面,它是一種編程思想的突破,它影響了許多其它的程式庫和框架以及編程語言。

使用觀察者模式

  • 創建:Rx可以方便的創建事件流和數據流
  • 組合:Rx使用查詢式的操作符組合和變換數據流
  • 監聽:Rx可以訂閱任何可觀察的數據流並執行操作

簡化代碼

  • 函數式風格:對可觀察數據流使用無副作用的輸入輸出函數,避免了程式里錯綜複雜的狀態 簡化代碼:Rx的操作符通通常可以將複雜的難題簡化為很少的幾行代碼
  • 非同步錯誤處理:傳統的try/catch沒辦法處理非同步計算,Rx提供了合適的錯誤處理機制
  • 輕鬆使用併發:Rx的Observables和Schedulers讓開發者可以擺脫底層的線程同步和各種併發問題

使用Observable的優勢

Rx擴展了觀察者模式用於支持數據和事件序列,添加了一些操作符,它讓你可以聲明式的組合這些序列,而無需關註底層的實現:如線程、同步、線程安全、併發數據結構和非阻塞IO。

 

Observable通過使用最佳的方式訪問非同步數據序列填補了這個間隙

單個數據                        多個數據
同步  T getData()                 Iterable<T> getData()
非同步  Future<T> getData()         Observable<T> getData()

 

Rx的Observable模型讓你可以像使用集合數據一樣操作非同步事件流,對非同步事件流使用各種簡單、可組合的操作。

Observable可組合

對於單層的非同步操作來說,Java中Future對象的處理方式是非常簡單有效的,但是一旦涉及到嵌套,它們就開始變得異常繁瑣和複雜。使用Future很難很好的組合帶條件的非同步執行流程(考慮到運行時各種潛在的問題,甚至可以說是不可能的),當然,要想實現還是可以做到的,但是非常困難,或許你可以用Future.get(),但這樣做,非同步執行的優勢就完全沒有了。從另一方面說,Rx的Observable一開始就是為組合非同步數據流準備的。

Observable更靈活

Rx的Observable不僅支持處理單獨的標量值(就像Future可以做的),也支持數據序列,甚至是無窮的數據流。Observable是一個抽象概念,適用於任何場景。Observable擁有它的近親Iterable的全部優雅與靈活。

Observable是非同步的雙向push,Iterable是同步的單向pull,對比:

事件           Iterable(pull)          Observable(push)
獲取數據        T next()                onNext(T)
異常處理        throws Exception        onError(Exception)
任務完成        !hasNext()              onCompleted()

 

Observable無偏見

Rx對於對於併發性或非同步性沒有任何特殊的偏好,Observable可以用任何方式實現,線程池、事件迴圈、非阻塞IO、Actor模式,任何滿足你的需求的,你擅長或偏好的方式都可以。無論你選擇怎樣實現它,無論底層實現是阻塞的還是非阻塞的,客戶端代碼將所有與Observable的交互都當做是非同步的。

Observable是如何實現的?

public Observable<data> getData();

 

  • 它能與調用者在同一線程同步執行嗎?
  • 它能非同步地在單獨的線程執行嗎?
  • 它會將工作分發到多個線程,返回數據的順序是任意的嗎?
  • 它使用Actor模式而不是線程池嗎?
  • 它使用NIO和事件迴圈執行非同步網路訪問嗎?
  • 它使用事件迴圈將工作線程從回調線程分離出來嗎?

從Observer的視角看,這些都無所謂,重要的是:使用Rx,你可以改變你的觀念,你可以在完全不影響Observable程式庫使用者的情況下,徹底的改變Observable的底層實現。

使用回調存在很多問題

回調在不阻塞任何事情的情況下,解決了Future.get()過早阻塞的問題。由於響應結果一旦就緒Callback就會被調用,它們天生就是高效率的。不過,就像使用Future一樣,對於單層的非同步執行來說,回調很容易使用,對於嵌套的非同步組合,它們顯得非常笨拙。

Rx是一個多語言的實現

Rx在大量的編程語言中都有實現,並尊重實現語言的風格,而且更多的實現正在飛速增加。

響應式編程

Rx提供了一系列的操作符,你可以使用它們來過濾(filter)、選擇(select)、變換(transform)、結合(combine)和組合(compose)多個Observable,這些操作符讓執行和複合變得非常高效。

你可以把Observable當做Iterable的推送方式的等價物,使用Iterable,消費者從生產者那拉取數據,線程阻塞直至數據準備好。使用Observable,在數據準備好時,生產者將數據推送給消費者。數據可以同步或非同步的到達,這種方式更靈活。

下麵的例子展示了相似的高階函數在Iterable和Observable上的應用

// Iterable getDataFromLocalMemory()
  .skip(10)
  .take(5)
  .map({ s -> return s + " transformed" })
  .forEach({ println "next => " + it }) // Observable getDataFromNetwork()
  .skip(10)
  .take(5)
  .map({ s -> return s + " transformed" })
  .subscribe({ println "onNext => " + it })

 

Observable類型給GOF的觀察者模式添加了兩種缺少的語義,這樣就和Iterable類型中可用的操作一致了:

  1. 生產者可以發信號給消費者,通知它沒有更多數據可用了(對於Iterable,一個for迴圈正常完成表示沒有數據了;對於Observable,就是調用觀察者的onCompleted方法)
  2. 生產者可以發信號給消費者,通知它遇到了一個錯誤(對於Iterable,迭代過程中發生錯誤會拋出異常;對於Observable,就是調用觀察者(Observer)的onError方法)

有了這兩種功能,Rx就能使Observable與Iterable保持一致了,唯一的不同是數據流的方向。任何對Iterable的操作,你都可以對Observable使用。

名詞定義

這裡給出一些名詞的翻譯

  • Reactive 直譯為反應性的,有活性的,根據上下文一般反以為反應式,響應式
  • Iterable 可迭代對象,支持以迭代器的形式遍歷,許多語言中都存在這個概念
  • Observable 可觀察對象,在Rx中定義為更強大的Iterable,在觀察者模式中是被觀察的對象,一旦數據產生或發生變化,會通過某種方式通知觀察者或訂閱者
  • Observer 觀察者對象,監聽Observable發射的數據並做出響應,Subscriber是它的一個特殊實現 *emit 直譯為發射,發佈,發出,含義是Observable在數據產生或變化時發送通知給Observer,調用Observer對應的方法,文章里一律譯為發射 *items 直譯為項目,條目,在Rx里是指Observable發射的數據項,文章里一律譯為數據,數據項

 https://github.com/mcxiaoke/RxDocs/blob/master/Intro.md


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文介紹了絕對定位元素其定位對其寬度的影響情況,並且根據絕對定位元素的內容類型不同進行探討,給出了自己總結的規律,以解決元素寬度顯示不對的問題。 ...
  • require和 sea的源碼分析,我之前的博客有寫過, 今天我想分享的是一個很簡單的核心代碼(不帶註釋和空行大概60行), 沒有容錯判斷。 require.js require函數實現用一句話概括: 依次載入require的模塊,然後監測script的onload事件,判斷所有模塊載入成功,執行r ...
  • float大概是css3以前網頁佈局里最常用的一個屬性了,經常看到一言不合就浮動的代碼,就一起來深入挖掘一下這個一半天使一半魔鬼的屬性吧。 本文是讀張鑫旭大神慕課網float視頻後的一些總結及一些拓展用法,視頻地址:http://www.imooc.com/learn/121。該視頻初讀很枯燥,認真 ...
  • 這個視圖對應的控制器是 這樣的話,這個date變數,是不會發生改變的,沒有觸發臟檢查,所以這時候要$apply方法,所有自定義的方法都要用$apply來觸發臟檢查 這樣那個日期就會變化了 $digest方法是觸動臟檢查的方法,為什麼不直接用這個呢,因為$apply會在執行時,運行一個eval語句,如 ...
  • 經常在別人的博客上有看到他們使用一些動態圖片來展示自己的項目運行效果。那麼,關於屏幕錄製與生成 Gif 圖要如何操作呢? 之前想著是不是用**等手機軟體錄製手機屏幕,然後利用**等播放器截取視頻 gif 圖。不過這些屏幕錄製的一般都帶水印。後面有找到方法,說 Android Studio 工具可以對 ...
  • 1.添加不同類型條目 2.常駐懸浮框使用 3.activity_app_manager.xml ...
  • AToolActivity.java SmsBackUp.java 1 package com.itheima.mobilesafe74.engine; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java ...
  • 新接觸一門程式或者開發框架,我一般都要先弄清楚程式的入口在哪裡,程式怎麼運行的;建立一個項目後,各個文件夾有什麼作用以及如何使用等等。理清楚這些東西對以後開發是很有好處的,古話說得好,工欲善其事,必先利其器。本文主要總結android程式的入口點和程式的運行流程(初識),android項目中各文件夾 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...