angular中的observable問題
angular的observable
類似于promise,angular里有observable來處理異步操作,接下來簡要介紹一下他。在使用observable之前,需要在相應(yīng)的組件里先引入
import { Observable } from 'rxjs';
例如,我想先創(chuàng)建一個(gè)發(fā)送異步請(qǐng)求的文件storage.service.ts,把它放在service里,哪里需要哪里引用。
可以發(fā)現(xiàn)observable的使用和promise類似,先new一個(gè)實(shí)例,該實(shí)例接受一個(gè)函數(shù)參數(shù),該函數(shù)參數(shù)內(nèi)部可實(shí)現(xiàn)異步操作,又有一個(gè)observer參數(shù),我們可以通過observer.next將異步數(shù)據(jù)拋出,這樣我們就能在外部接收到該參數(shù)。
?// observable 使用之前先引入 ? getObservable(){ ? ? return new Observable((observer)=>{ ? ? ? setTimeout(()=>{ ? ? ? ? var data = 'observer數(shù)據(jù)' ? ? ? ? observer.next(data) ? ? ? ? ? ? ? ?//相當(dāng)于promise的resolve ? ? ? },2000) ? ? }) ? }
現(xiàn)在我們需要在home組件中使用,注意:需要先在home.ts引入storage.service.ts,然后在consructor中定義變量
import { StorageService } from 'src/app/services/storage.service'; ? constructor(public storage:StorageService) { }
之后便可在home組件中拿到observer.next拋出的數(shù)據(jù)
let oberverData = this.storage.getObservable() ? let d = oberverData.subscribe((res)=>{ ? ? ? ?//相當(dāng)于promise的then ? ? ? console.log(res) })
與promise不同的是,observable功能更加強(qiáng)大。
1、取消訂閱
observable可以在訂閱之后,取消訂閱
setTimeout(()=>{ ? ? ? d.unsubscribe() ? ? ? ? ? ?//一秒鐘之后取消訂閱,接收不到消息 },1000)
2、多次輸出
promise的狀態(tài)一旦從pending變?yōu)閞eject或resolve后,就不會(huì)發(fā)生改變,因此他不能多次輸出resolve出的值,但observable可以實(shí)現(xiàn)多次輸出。例
let p = new Promise(resolve=>{ ? ? ? setInterval(()=>{ ? ? ? ? resolve('promise interval值') ? ? ? },2000) }) p.then(res=>console.log(res)) ? ? //只輸出一次 ? // observable let o = new Observable(observer=>{ ? ? setInterval(()=>{ ? ? ? ?observer.next('observable interval值') ? ? },2000) }) o.subscribe(res=>console.log(res)) ? ?//每隔2秒輸出一次
3、使用pipe對(duì)拋出的數(shù)據(jù)進(jìn)行處理
let o1 = this.storage.getObservable1() o1.pipe( ? ?filter((data:any)=> { ? ? ? return data%2 == 0 ? ?}), ? ?map(value => { ? ? ? return value*value ? ?}) ).subscribe(res=>console.log(res))
angular observable數(shù)據(jù)類型的單元測(cè)試數(shù)據(jù)準(zhǔn)備
我有一個(gè)Component,其items屬性是一個(gè)嵌套的Observable:
items$: Observable<Observable<Product>[]> = this.componentData$.pipe( map((data) => data.productCodes.trim().split(' ')), map((codes) => codes.map((code) => this.productService.get(code, this.PRODUCT_SCOPE)) ) );
ComponentData$的類型:
private componentData$: Observable<model> = this.componentData.data$.pipe( filter(Boolean) );
Model的定義:
componentData$類型為Observable,調(diào)用map的回調(diào)里又嵌入了map操作,這是返回類型為嵌套Observable的原因。
因?yàn)閕tems 是 從componentData是從componentData 是從componentData得來的,而componentData$又來自componentData,因此我只用考慮如何構(gòu)造componentData測(cè)試數(shù)據(jù)就行了:
private componentData$: Observable<model> = this.componentData.data$.pipe( filter(Boolean) );
下面看看如何在單元測(cè)試用例里創(chuàng)建mock數(shù)據(jù):MockCmsProductCarouselComponent:
完整解決方案
const mockComponentData: CmsProductCarouselComponent = { uid: '001', typeCode: 'ProductCarouselComponent', modifiedTime: new Date('2017-12-21T18:15:15+0000'), popup: 'false', productCodes: productCodeArray.join(' '), scroll: 'ALLVISIBLE', title: 'Mock Title', name: 'Mock Product Carousel', container: 'false', }; const MockCmsProductCarouselComponent = <CmsComponentData<any>>{ data$: of(mockComponentData), };
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
angular5 子組件監(jiān)聽父組件傳入值的變化方法
今天小編就為大家分享一篇angular5 子組件監(jiān)聽父組件傳入值的變化方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09Angular應(yīng)用prerender預(yù)渲染提高頁面加載速度
這篇文章主要介紹了Angular應(yīng)用prerender預(yù)渲染提高頁面加載速度,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Angular企業(yè)級(jí)開發(fā)——MVC之控制器詳解
本篇文章主要介紹了Angular企業(yè)級(jí)開發(fā)——MVC之控制器詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Angular.js中window.onload(),$(document).ready()的寫法淺析
這篇文章主要介紹了Angular.js中window.onload(),$(document).ready()的寫法淺析,需要的朋友可以參考下2017-09-09angularjs 中$apply,$digest,$watch詳解
這篇文章主要介紹了angularjs 中$apply,$digest,$watch詳解的相關(guān)資料,需要的朋友可以參考下2016-10-10Angular在一個(gè)頁面中使用兩個(gè)ng-app的方法(二)
這篇文章主要介紹了Angular在一個(gè)頁面中使用兩個(gè)ng-app的方法(二),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02