亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

shenhualong / 3217人閱讀

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

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

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

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

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

[TOC]

一. 劃重點(diǎn)

RxJS-DOM

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

冷熱Observable

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

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

涉及的運(yùn)算符

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

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

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

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

import { Injectable } from "@angular/core";
import { Observable, of } from "rxjs";
import { MessageService } from "./message.service";//某個(gè)自定義的服務(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請(qǐng)求*/
  getHeroes(): Observable>{
    return this.http.get(this.all_hero_api,{observe:"response"});
  }

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

express中寫一些用于測(cè)試的虛擬數(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"]);
})
}

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

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

盡管看起來(lái)Http請(qǐng)求的返回結(jié)果是一個(gè)可觀測(cè)對(duì)象,但是它卻沒有map方法,當(dāng)需要對(duì)http請(qǐng)求返回的可觀測(cè)對(duì)象進(jìn)行操作時(shí),可以使用pipe操作符來(lái)實(shí)現(xiàn):

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

/*構(gòu)建一個(gè)模擬的結(jié)果處理管道
*map操作來(lái)獲取數(shù)據(jù)
*tap實(shí)現(xiàn)日志
*flatMap實(shí)現(xiàn)結(jié)果自動(dòng)遍歷
*filter實(shí)現(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)換為逐個(gè)發(fā)出的數(shù)據(jù),并過濾掉了不符合條件的項(xiàng):

3.2 常見的操作符

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

四. 冷熱Observable的兩種典型場(chǎng)景

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

4.1 shareReplay與請(qǐng)求緩存

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

先回顧一下上面的http請(qǐng)求代碼:

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

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

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

4.2 share與異步管道

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

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

示例:

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

一定要好好讀官方文檔。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/110248.html

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

    JayChen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<