成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【響應(yīng)式編程的思維藝術(shù)】 (5)Angular中Rxjs的應(yīng)用示例

shenhualong / 3161人閱讀

摘要:本文是響應(yīng)式編程第四章構(gòu)建完整的應(yīng)用程序這篇文章的學(xué)習(xí)筆記。涉及的運算符每隔指定時間將流中的數(shù)據(jù)以數(shù)組形式推送出去。中提供了一種叫做異步管道的模板語法,可以直接在的微語法中使用可觀測對象示例五一點建議一定要好好讀官方文檔。

本文是【Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的Web應(yīng)用程序】這篇文章的學(xué)習(xí)筆記。

示例代碼托管在:http://www.github.com/dashnowords/blogs

博客園地址:《大史住在大前端》原創(chuàng)博文目錄

華為云社區(qū)地址:【你要的前端打怪升級指南】

[TOC]

一. 劃重點

RxJS-DOM

原文示例中使用這個庫進行DOM操作,筆者看了一下github倉庫,400多星,而且相關(guān)的資料很少,所以建議理解思路即可,至于生產(chǎn)環(huán)境的使用還是三思吧。開發(fā)中Rxjs幾乎默認是和Angular技術(shù)棧綁定在一起的,筆者最近正在使用ionic3進行開發(fā),本篇將對基本使用方法進行演示。

冷熱Observable

冷Observable從被訂閱時就發(fā)出整個值序列

熱Observable無論是否被訂閱都會發(fā)出值,機制類似于javascript事件。

涉及的運算符

bufferWithTime(time:number)-每隔指定時間將流中的數(shù)據(jù)以數(shù)組形式推送出去。

pluck(prop:string)- 操作符,提取對象屬性值,是一個柯里化后的函數(shù),只接受一個參數(shù)。

二. Angular應(yīng)用中的Http請求

Angular應(yīng)用中基本HTTP請求的方式:

import { Injectable } from "@angular/core";
import { Observable, of } from "rxjs";
import { MessageService } from "./message.service";//某個自定義的服務(wù)
import { HttpClient, HttpParams, HttpResponse } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class HeroService {
  private localhost = "http://localhost:3001";
  private all_hero_api = this.localhost + "/hero/all";//查詢所有英雄
  private query_hero_api = this.localhost + "/hero/query";//查詢指定英雄

  constructor(private http:HttpClient) {
  }
  
  /*一般get請求*/
  getHeroes(): Observable>{
    return this.http.get(this.all_hero_api,{observe:"response"});
  }

  /*帶參數(shù)的get請求*/
  getHero(id: number): Observable>{
    let params = new HttpParams();
        params.set("id", id+"");
        return this.http.get(this.query_hero_api,{params:params,observe:"response"});
  }
  
  /*帶請求體的post請求,any可以自定義響應(yīng)體格式*/
  createHero(newhero: object): Observable>{
      return this.http.post>(this.create_hero_api,{data:newhero},{observe:"response"});
  } 
}

express中寫一些用于測試的虛擬數(shù)據(jù):

var express = require("express");
var router = express.Router();

/* GET home page. */
router.get("/all", function(req, res, next) {
  let heroes = [{
    index:1,
    name:"Thor",
    hero:"God of Thunder"
  },{
    index:2,
    name:"Tony",
    hero:"Iron Man"
  },{
    index:3,
    name:"Natasha",
    hero:"Black Widow"
  }]
  res.send({
     data:heroes,
     result:true
  })
});

/* GET home page. */
router.get("/query", function(req, res, next) {
  console.log(req.query);
  let hero= {
    index:4,
    name:"Steve",
    hero:"Captain America"
  }
  res.send({
     data:hero,
     result:true
  })
});


/* GET home page. */
router.post("/create", function(req, res, next) {
  console.log(req.body);
  let newhero = {
     index:5,
     name:req.body.name,
     hero:"New Hero"
  }
  res.send({
     data:newhero,
     result:true
  })
});

module.exports = router;

在組件中調(diào)用上面定義的方法:

sendGet(){
 this.heroService.getHeroes().subscribe(resp=>{
   console.log("響應(yīng)信息:",resp);
   console.log("響應(yīng)體:",resp.body["data"]);
 })
}

sendQuery(){
this.heroService.getHero(1).subscribe(resp=>{
  console.log("響應(yīng)信息:",resp);
  console.log("響應(yīng)體:",resp.body["data"]);
})
}

sendPost(){
this.heroService.createHero({name:"Dash"}).subscribe(resp=>{
  console.log("響應(yīng)信息:",resp);
  console.log("響應(yīng)體:",resp.body["data"]);
})
}

控制臺打印的信息可以看到后臺的虛擬數(shù)據(jù)已經(jīng)被請求到了:

三. 使用Rxjs構(gòu)建Http請求結(jié)果的處理管道 3.1 基本示例

盡管看起來Http請求的返回結(jié)果是一個可觀測對象,但是它卻沒有map方法,當需要對http請求返回的可觀測對象進行操作時,可以使用pipe操作符來實現(xiàn):

import { Observable, of, from} from "rxjs";
import { map , tap, filter, flatMap }from "rxjs/operators";

/*構(gòu)建一個模擬的結(jié)果處理管道
*map操作來獲取數(shù)據(jù)
*tap實現(xiàn)日志
*flatMap實現(xiàn)結(jié)果自動遍歷
*filter實現(xiàn)結(jié)果過濾
*/
getHeroes$(): Observable>{
    return this.http.get(this.all_hero_api,{observe:"response"})
    .pipe(
          map(resp=>resp.body["data"]),
          tap(this.log),
          flatMap((data)=>{return from(data)}),
          filter((data)=>data["index"] > 1)
    );
}

很熟悉吧?經(jīng)過處理管道后,一次響應(yīng)中的結(jié)果數(shù)據(jù)被轉(zhuǎn)換為逐個發(fā)出的數(shù)據(jù),并過濾掉了不符合條件的項:

3.2 常見的操作符

Angular中文網(wǎng)列舉了最常用的一些操作符,RxJS官方文檔有非常詳細的示例及說明,且均配有形象的大理石圖,建議先整體瀏覽一下有個印象,有需要的讀者可以每天熟悉幾個,很快就能上手,運算符的使用稍顯抽象,且不同運算符的組合使用在流程控制和數(shù)據(jù)處理方面的用法靈活多變,也是有很多套路的,開發(fā)經(jīng)驗需要慢慢積累。

四. 冷熱Observable的兩種典型場景

原文中提到的冷熱Observable的差別可以參考這篇文章【RxJS:冷熱模式的比較】,概念本身并不難理解。

4.1 shareReplay與請求緩存

開發(fā)中常會遇到這樣一種場景,某些集合型的常量,完全是可以復(fù)用的,通常開發(fā)者會將其進行緩存至某個全局單例中,接著在優(yōu)化階段,通過增加一個if判斷在請求之前先檢查緩存再決定是否需要請求,Rxjs提供了一種更優(yōu)雅的實現(xiàn)。

先回顧一下上面的http請求代碼:

getHeroes(): Observable>{
   return this.http.get(this.all_hero_api,{observe:"response"});
}

http請求默認返回一個冷Observable,每當返回的流被訂閱時就會觸發(fā)一個新的http請求,Rxjs中通過shareReplay( )操作符將一個可觀測對象轉(zhuǎn)換為熱Observable(注意:shareReplay( )不是唯一一種可以加熱Observable的方法),這樣在第一次被訂閱時,網(wǎng)絡(luò)請求被發(fā)出并進行了緩存,之后再有其他訂閱者加入時,就會得到之前緩存的數(shù)據(jù),運算符的名稱已經(jīng)很清晰了,【share-共享】,【replay-重播】,是不是形象又好記。對上面的流進行一下轉(zhuǎn)換:

  getHeroes$(): Observable>{
    return this.http.get(this.all_hero_api,{observe:"response"})
    .pipe(
      map(resp=>resp.body["data"]),
      tap(this.log),
      flatMap((data)=>{return from(data)}),
      filter((data)=>data["index"] > 1),
      shareReplay() // 轉(zhuǎn)換管道的最后將這個流轉(zhuǎn)換為一個熱Observable
    )
  }

在調(diào)用的地方編寫調(diào)用代碼:

sendGet(){
     let obs = this.heroService.getHeroes$();
     //第一次被訂閱
     obs.subscribe(resp=>{
       console.log("響應(yīng)信息:",resp);
     });
    //第二次被訂閱
     setTimeout(()=>{
       obs.subscribe((resp)=>{
         console.log("延遲后的響應(yīng)信息",resp);
       })
     },2000)
}

通過結(jié)果可以看出,第二次訂閱沒有觸發(fā)網(wǎng)絡(luò)請求,但是也得到了數(shù)據(jù):

網(wǎng)絡(luò)請求只發(fā)送了一次(之前的會發(fā)送兩次):

4.2 share與異步管道

這種場景筆者并沒有進行生產(chǎn)實踐,一是因為這種模式需要將數(shù)據(jù)的變換處理全部通過pipe( )管道來進行,筆者自己的函數(shù)式編程功底可能還不足以應(yīng)付,二來總覺得很多示例的使用場景很牽強,所以僅作基本功能介紹,后續(xù)有實戰(zhàn)心得后再修訂補充。Angular中提供了一種叫做異步管道的模板語法,可以直接在*ngFor的微語法中使用可觀測對象:

  • {{contact.name}}
  • {{contact.name}}

示例:

this.contacts = http.get("contacts.json")
                    .map(response => response.json().items)
                    .share();
setTimeout(() => this.contacts2 = this.contacts, 500);
五. 一點建議

一定要好好讀官方文檔。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/110248.html

相關(guān)文章

  • 響應(yīng)編程思維藝術(shù)】 (1)Rxjs專題學(xué)習(xí)計劃

    摘要:由于技術(shù)棧的學(xué)習(xí),筆者需要在原來函數(shù)式編程知識的基礎(chǔ)上,學(xué)習(xí)的使用。筆者在社區(qū)發(fā)現(xiàn)了一個非常高質(zhì)量的響應(yīng)式編程系列教程共篇,從基礎(chǔ)概念到實際應(yīng)用講解的非常詳細,有大量直觀的大理石圖來輔助理解流的處理,對培養(yǎng)響應(yīng)式編程的思維方式有很大幫助。 showImg(https://segmentfault.com/img/bVus8n); [TOC] 一. 響應(yīng)式編程 響應(yīng)式編程,也稱為流式編程...

    lscho 評論0 收藏0
  • 響應(yīng)編程思維藝術(shù)】 (2)響應(yīng)Vs面向?qū)ο?/b>

    摘要:本文是響應(yīng)式編程第一章響應(yīng)式這篇文章的學(xué)習(xí)筆記。通過代碼對比可以發(fā)現(xiàn),在響應(yīng)式編程中,我們不再用對象的概念來對現(xiàn)實世界進行建模,而是使用流的思想對信息進行拆分和聚合。 本文是Rxjs 響應(yīng)式編程-第一章:響應(yīng)式這篇文章的學(xué)習(xí)筆記。示例代碼地址:【示例代碼】 更多文章:【《大史住在大前端》博文集目錄】 showImg(https://segmentfault.com/img/bVbuE...

    Tonny 評論0 收藏0
  • 響應(yīng)編程思維藝術(shù)】 (3)flatMap背后代數(shù)理論Monad

    摘要:本文是響應(yīng)式編程第二章序列的深入研究這篇文章的學(xué)習(xí)筆記。函數(shù)科里化的基本應(yīng)用,也是函數(shù)式編程中運算管道構(gòu)建的基本方法。四資料參考函數(shù)式編程指南 本文是Rxjs 響應(yīng)式編程-第二章:序列的深入研究這篇文章的學(xué)習(xí)筆記。示例代碼托管在:http://www.github.com/dashnowords/blogs 更多博文:《大史住在大前端》目錄 showImg(https://segme...

    MorePainMoreGain 評論0 收藏0
  • 【CuteJavaScript】Angular6入門項目(3.編寫服務(wù)和引入RxJS

    摘要:發(fā)布通過回調(diào)方法向發(fā)布事件。觀察者一個回調(diào)函數(shù)的集合,它知道如何去監(jiān)聽由提供的值。 本文目錄 一、項目起步 二、編寫路由組件 三、編寫頁面組件 1.編寫單一組件 2.模擬數(shù)據(jù) 3.編寫主從組件 四、編寫服務(wù) 1.為什么需要服務(wù) 2.編寫服務(wù) 五、引入RxJS 1.關(guān)于RxJS 2.引入RxJS 3.改造數(shù)據(jù)獲取方式 六、改造組件 1.添...

    RebeccaZhong 評論0 收藏0
  • 從命令響應(yīng)(一)

    摘要:響應(yīng)式命令式這兩種編程風格的思維方式是完全相反的。第二種方式是工人主動去找工人索取生產(chǎn)手機所要的零件,然后生產(chǎn)一臺完整的手機,這兩種方式就對應(yīng)的響應(yīng)式和命令式。 angular2中內(nèi)置了rxjs,雖然框架本身并沒有強制開發(fā)者使用響應(yīng)式風格來組織代碼,但是從框架開發(fā)團隊的角度可以看出他們必然是認同這種編程風格的。rxjs本質(zhì)是基于函數(shù)式編程的響應(yīng)式風格的庫,函數(shù)式相對于面向?qū)ο髞碚f更加抽...

    JayChen 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<