摘要:最近有同學在使用時總是不能如愿拿到自己想要的數據,說到底還是沒有能把思維從命令式的習慣中轉換過來。響應式的編程風格中,數據應該在流內完成轉換,合并,過濾,而不是取出來,一頓操作再丟回流里。
最近有同學在使用rxjs時總是不能如愿拿到自己想要的數據,說到底還是沒有能把思維從命令式的習慣中轉換過來。
Observable !== 異步 && Observable !== 同步如題,請默念幾遍!在(一)里面其實就提到過,Observable里的數據到底是同步的還是異步取決于你如何使用,這和promise是完全不同的,promise不論你如果使用,它始終是異步的。上代碼:
dataSource: DataSource; ngOnInit() { this.getDataSource() .subscribe(data => { console.log("in subscribe: ",data); this.dataSource = data; }) console.log("after subscribe:", this.dataSource); } getDataSource(): Observable > { return this.stockService.getStocksMat() .pipe( map(stocks => new StockTbDataSource(this.paginator, this.sort, stocks)) ); };
請問,以上2個console,哪個先輸出,哪個后輸出?正確答應該是,鬼知道!仔細分析代碼,這個數據是從stockService上獲取到的,那么數據是同步還是異步就取決于這個服務的 getStocksMat 方法。
import { of } from "rxjs"; export class StockService { getStocksMat(): Observable> { return of({name: "a", price: 100}); } }
現在呢,毫無疑問,這個時候數據是同步的,因為服務的方法中使用of操作符創建了一個 Observable,of操作符的行為是會把傳入它的參數依次推送到流上,最后發出完成通知。所以,以上兩個console的輸出順序應該是 inner 先輸出,after 后輸出。
注意:也不要把操作符和同步異步劃等號,同樣也和你如何使用它有關系,這個系列里一直沒有提到的一個東西叫 scheduler,也就是調度器,它可以調節流上的值如何發射
import { asyncScheduler } from "rxjs"; of({name: "a", price: 100}, asyncScheduler); // 此時流上的數據將被異步發出。
假如service上的代碼變成:
export class StockService { constructor(private http: HttpClient) { } getStocksMat(): Observable> { return this.http.get(someUrl).pipe( map(res => res.data) ); } }
很顯然,我們是想從服務器上取一段數據回來,那么這個過程肯定是異步的,所以那2個console的輸出順序就應該是 after 先輸出,而inner 后輸出。
盡量不要主動訂閱流這里指的是在angular里,因為angular給我們提供了取數據的 pipe - async。它可以幫助我們在模板中把數據取出來,當然就是訂閱我們給它的 Observable。不主動訂閱的原因如下:
當訂閱流時,會產生 subscription,當然使用 async pipe 時也會有,但此時框架會幫我們管理它,當不需要再訂閱時取消訂閱,如模板銷毀時。
如果我們手動訂閱的是一個會發出結束通知的流時,rxjs的底層會幫我們在流上的數據發送完成時取消訂閱,反之則不會。也就是說第一,你需要準確判斷訂閱的流是否會發出結束通知。第二,你可能需要在合適的時機手動取消訂閱。
響應式的編程風格中,數據應該在流內完成轉換,合并,過濾,而不是取出來,一頓操作再丟回流里。
如下
export class StockService { constructor(private http: HttpClient) { } getStocksMatArr(): Observable[]> { return this.http.get(someUrl).pipe( map(res => res.data) ); } // 只要價格大于某個值的股票 getStocksThatPriceLargeThan(price: number): Observable []> { return this.getStocksMatArr().pipe( filter(stocks => stocks.filter(stock => stock.price > price)) ) } // 和另外一些流上的數據組合,比如購買人數; getStocksWithBuyCount(): Observable<{stocks: DataSource []; count: number}> { const count$ = of(2000); return this.getStocksMatArr().pipe( withLatestFrom(count$, (stocks, count) => ({stocks, count})) ); } // 當然還可以更復雜 showExample(): Observable { return this.getStocksMatArr().pipe( mergeMap(stocks => from(stocks)), // 先把stock逐個放到流上 filter(stock => stock.price < 50), // 過濾出來 take(10), // 拿前10支股票 withLatestFrom(obs), // 和另一條流的上數據組合 bufferCount(2), // 兩兩組合 reduce((acc, cur) => [...acc, cur], []) // 再合并起來 delay(2000), // 延遲2秒再發 ... 等等, 一切取決于你的需求。 ) } }
只要保持數據一直在流中,你就不必時時惦記著它到底是同步還異步,數據來了就消費,沒來就一直等。剛開始時建議強迫自己不去訂閱,這樣才能很快的理解和適應響應式的風格。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97258.html
摘要:上一章通過用戶注冊講解了響應式表單,這章主要講解如何向服務器提交注冊數據并導航到好友信息模塊。利用的方法將這個憑證存儲到本地。針對一個進行數據存儲。當用戶關閉瀏覽器窗口后,數據會被刪除。 上一章通過用戶注冊講解了響應式表單ReactiveForm,這章主要講解如何向服務器提交注冊數據并導航到好友信息模塊。 提交注冊信息 向服務器提交信息是通過模板中標簽中的(ngSubmit)=onSu...
摘要:上一章通過用戶注冊講解了響應式表單,這章主要講解如何向服務器提交注冊數據并導航到好友信息模塊。利用的方法將這個憑證存儲到本地。針對一個進行數據存儲。當用戶關閉瀏覽器窗口后,數據會被刪除。 上一章通過用戶注冊講解了響應式表單ReactiveForm,這章主要講解如何向服務器提交注冊數據并導航到好友信息模塊。 提交注冊信息 向服務器提交信息是通過模板中標簽中的(ngSubmit)=onSu...
摘要:所以一個網,甚至是響應式設計,在兩個平臺上都會損害您整體的。三響應式與如果把網站作為一個單獨的網站,如果網站的內容與桌面版的內容相對缺少,導致用戶回到桌面端的網站,會記錄這種選擇,使搜索排名降低,國內百度就不知道會怎樣。 一、為什么需要響應式設計(responsible web design) 1. 響應式發展背景 1、屏幕尺寸的快速變化,iphone為320x480,分辨率在未來可以...
摘要:垂直居中相關知識總結前言工作中用到了很多關于垂直居中相關的知識之前,在上提問了個問題關于垂直居中,大家有沒有什么比較好的建議。 垂直居中相關知識總結 前言 工作中用到了很多關于垂直居中相關的知識之前,在SF上提問了個問題CSS關于垂直居中,大家有沒有什么比較好的建議。非常感謝各位前輩對我的幫助,前輩們給的答案都非常多也各式各樣,我覺得有必要把大家的回答總結一下。 方法總結 一、絕對定...
閱讀 2871·2021-10-14 09:43
閱讀 1658·2021-09-29 09:34
閱讀 1744·2021-07-28 00:16
閱讀 2964·2019-08-30 15:53
閱讀 2905·2019-08-30 13:59
閱讀 2961·2019-08-30 13:57
閱讀 1091·2019-08-26 13:38
閱讀 1894·2019-08-26 13:25