首頁>技術>

出處:https://mp.weixin.qq.com/s?__biz=Mzg4MjE5OTI4Mw==&mid=2247486025&idx=1&sn=a14f28a3cb02d03a664d87201a428bd1

在 Reactive 方面,有兩個非常知名的工程師,他們是來自 Netfix 的 RxJava 作者Ben Christensen 和 RxJS 作者 Ben Lesh,兩人在 Reactive 方面都做出了非常多的貢獻。在 2019 年初 Reactive 社群有兩個非常令人振奮的訊息,RSocket 步入了大眾視野,RSocket 是二進位制非同步化通訊協議,完全相容 Reactive 語義,提供了多種通訊模型,而且是對等通訊;此外就是 Svelte 3.0 釋出,Svelte 作者 Rich Harris 做了知名的 “Rethinking Reactivity” 的演講。Svelte 透過編譯器的方式讓Reactive 使用更簡單,沒有 Virtual DOM 等效能損失,程式碼更小效能更高。當然在 Reactive 社群,RxJS 還是最核心的底層框架,始終發揮著重大作用。這篇文章,我們就討論一下如何基於 RxJS 銜接 RSocket 和 Svelte, 在前端開發中全面擁抱 Reactivity,那麼就從 Svelte 開始吧。

Svelte

Svelte 框架的核心理念是 Reactive,但是和其他前端框架不太一樣的是,Svelte 是透過靜態編譯實現 Reactive,同時並減少框架執行時的程式碼量,這點你可以在 Svelte 作者 Rich Harris 的 《Svelte 3: Rethinking reactivity》 文章和演講中瞭解到。

Svelte 語法簡潔,幫助您編寫更少的樣板程式碼。雖然同樣是實現 Reactivity,對比RxJS,Svelte 的入門門檻非常低,你幾乎不需要理解和 Reactive 相關的知識,就可以編寫全響應式的 UI 應用。

Svelte 包含對 RxJS 的支援,如 RxJS 的 Observable 變數,另外體現在自定義Store 上,如和 RxJS 的 BehaviorSubject 的整合。Svelte 主要是關注在 UI 層面的 Reactivity,如 state 管理,事件處理等,但是涉及到邏輯處理,如後臺互動的 fetch,WebSocket,流式資料等,可能 RxJS 會更方便,這方面也是 RxJS 非常擅長的。讓我們看一下典型的幾個例子:

RxJS 的 interval 應用

你可以透過 RxJS 的 interval 進行定時狀態更新,同時可以實現非常複雜的邏輯:

<script>  import { interval } from "rxjs";  import { map, take,startWith} from "rxjs/operators";  const counter = interval(1000).pipe(    map(i => i + 1),    startWith(0),    take(10)  );</script><h2>Count to 10</h2>{$counter}
RxJS BehaviorSubject物件

RxJS 的 BehaviorSubject 可以在 Svelte 中直接使用,和 Svelte 的狀態管理發揮著同樣的作用。

<script>   const store1 = new BehaviorSubject(0);   store1.set = store1.next;</script><button on:click={()=>{store1.next(1)}}>increment 1</button><button on:click={()=>{$store1 = 2}}>increment 2</button>{$store1}
RxJS的fromFetch

結合 RxJS 的 fromFetch ,可以非常容易地和後端進行互動,完全是響應式的。

<script>   const  data = fromFetch('https://httpbin.org/ip', {    selector: response => response.json()  });</script><h2>Your IP: </h2>{$data.origin}

當然你可以可以結合 RxJS 的 WebSocket 特性完成和 WebSocket 的互動。詳細細節可以參考 https://rxjs-dev.firebaseapp.com/api/webSocket/webSocket。

RSocket

Svelte 和 RxJS 互動解決 UI 和基本的後端通訊是沒有問題的,如 HTTP REST API 和 WebSocket 等,那麼為何還需要 RSocket?讓我們先看一下 RSocket 的通訊模型:

request/response: 這也是典型的 HTTP 請求模型,也適用於 RPC 場景,當然這個通訊是非同步化的,也適用 Promise 模型。request/stream: 流式資料請求,如 Pub/Sub 模型,可以非常方便地後端的資料流,如來自 Kafka 訊息等。fireAndForget: 不需要返回確認的場景,如資料採集後提交後端的場景,這樣速度更快。Channel:雙向通訊,如 IM 聊天場景,可以同時實現訊息的傳送和接收。

標準的請求響應,如 HTTP REST API,可以使用 request/response;資料採集,我們可以使用 fireAndForget 做到效能極致;如果是訊息訂閱或者流式資料處理,你可以使用 request/stream;如果你要在 web 頁面中新增即時訊息(IM)聊天場景,使用 Channel 即可。一句話,藉助於 RSocket 這一協議,可以讓你實現各種通訊場景的需求。RSocket 完全是基於 Reactive 語義的,這樣和 RxJS 和 Svelte 可以無縫銜接,不需要額外的轉換操作。

此外 RSocket 還支援對等通訊,也就是通訊的雙方或者多方,同時可以為 client 或者 server。我們都知道 Svelte Store 都是針對元件通訊的,如果 Svelte Store 和RSocket 整合,則可以實現不同頁面之間的通訊,頁面之間的協作場景就可以非常容易完成。

目前 RSocket 對 JavaScript 支援主要包括三個方面:RSocket Browser,在瀏覽器中連線後端 RSocket 服務;RSocket Node.js 可以快速建立後端 RSocket 服務;RSocket Deno 可以建立基於 Deno 的後端 RSocket 服務。

關於 Svelte 和 RSocket 通訊,可以參考 https://github.com/linux-china/svelte-rsocket-demo,詳細的結構圖如下:

RxJS 起著銜接 Svelte 和 RSocket 的功能,主要是 RxJS 本身的強大功能。所以接下來我們介紹一下即將釋出的 RxJS 7.0 的新特性和功能。

RxJS 7.0 採用最新的 TS 版本(當前為 4.0.x),這樣可以使用 TypeScript 最新的特性,這樣程式碼就整潔很多,當然可靠性和穩定性也提高很多。

RxJS toPromise 的調整

RxJS 的 Observable 是可以轉換為 Promise 物件的,但是 API 讓一些人有些模糊,主要的原因是 Observable 是流式的資料,所以在 RxJS 7.0 中使用 firstValueFrom, lastValueFrom 來替換 toPromise 函式,程式碼如下:

import {firstValueFrom, lastValueFrom} from "rxjs";let result = await firstValueFrom(observable);
基於 AsyncIterable 構建 Observable

AsyncIterable 在非同步化越來越重要, 如熟知的 for await...of 語句,就是在非同步可迭代物件上建立一個迭代迴圈。在 RxJS 7.0中,我們可以基於 AsyncIterable 建立 Observable 物件,然後就可以利用 Observable 強大的功能來處理非同步可以迭代物件列表。

from(iterable).subscribe(x => console.log(x))

當然如果你想將Observable轉換為AsyncIterables,可以參考Ben Lesh的 https://github.com/benlesh/rxjs-for-await 專案。

fromFetch 函式提示

fromFetch 做了提升,添加了一個 selector 函式,這樣可以支援直接從 response 提取對應的資訊,如轉換為文字或者 json 物件等,之前需要進行 map 轉換的,現在方便非常多。

fromFetch("http://httpbin.org/ip", {selector: response => response.json()});
RxJS 和 Deno

Deno 作為一個新的 JS 執行引擎,因其的安全性、內建 TypeScript 支援和分散式的 module 載入機制,越來越受到 JavaScript 開發者的關注。RxJS 是基於 TypeScript 編寫的,所以 Deno 的原生 TypeScript 支援沒有問題。

此外 Deno 的 API 設計遵循 Web APIs 規範,如 fetch 函式、WebSocket 類,這就讓 RxJS 的 fromFetch 和 WebSocket 可以在 Deno 使用,可以直接在 Deno 中使用 RxJS 網路通訊相關的功能,此外 RSocket 也包括對 Deno 的支援,也可以使用 RSocket 進行網路通訊。

在 Deno 中使用 RxJS fromFetch 樣例如下:

import {firstValueFrom} from "https://esm.sh/[email protected]?no-check";import {fromFetch} from "https://esm.sh/[email protected]/fetch?no-check";const ip = await firstValueFrom(fromFetch("http://httpbin.org/ip", {selector: response => response.json()}));console.log(ip.origin);
RxJS 7.0 其他

如記憶體最佳化,使用記憶體更小,新增更多 operator 方法。當然大家也不用太擔心相容性的問題,目前 RxJS 7.0 只是增加一些 API,只會將一些 API 調整為廢棄 (Deprecated) 狀態,還不會刪除掉,可能在 RxJS 8 中會進行刪除,所以 RxJS 7.0 的相容性不用太擔心。

當然 RxJS 7.0 還有更多更新,詳細資訊請參考:https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md

總結

對比語法層級的 Promise(async/await),Reactive 確實複雜不少,可能需要花費你不少時間去掌握。但是也不是完全無法掌握的,Svelte 讓 Reactive UI 變得非常簡單,你幾乎不需要了解什麼是 Reactive;RSocket 基於 Reactive語義對通訊模型進行抽象化,通訊模型簡單很多且能覆蓋多種業務場景;而 RxJS 強大的功能,可以很好地粘合多項技術,如 Svelte 和 RSocket,擁抱 Reatctivity 毫無壓力。

出處:https://mp.weixin.qq.com/s?__biz=Mzg4MjE5OTI4Mw==&mid=2247486025&idx=1&sn=a14f28a3cb02d03a664d87201a428bd1

12
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 深入淺出談Java單例模式,多例模式設計