Angular异步数据流编程

1 目前常见的异步编程的几种方法

首先给出一个异步请求的实例:

java 复制代码
import {Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData() {
    setTimeout(() => {
      let res = 'zhaoshuai-lc'
      return res
    }, 3000)
  }
}
java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit{

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    let data = this.RequestServiceService.getData()
    console.log(data)
  }
}

1.1 回调函数解决问题

java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit{

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    this.RequestServiceService.getData(data => {
      console.log(data)
    })
  }
}
java 复制代码
import {Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData(callBack) {
    setTimeout(() => {
      let res = 'zhaoshuai-lc'
      callBack(res)
    }, 3000)
  }
}

1.2 Promise 处理异步

java 复制代码
import {Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        let res = 'zhaoshuai-lc'
        resolve(res)
      }, 3000)
    })

  }
}
java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    let promiseData = this.RequestServiceService.getData()
    promiseData.then(data => {
      console.log(data)
    })
  }
}

1.3 RxJS 处理异步

java 复制代码
import {Injectable} from '@angular/core';
import {Observable} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData() {
    return new Observable(observer => {
      setTimeout(() => {
        let res = 'zhaoshuai-lc'
        observer.next(res)
      }, 3000)
    })
  }
}
java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    let observableData = this.RequestServiceService.getData()
    observableData.subscribe(data => {
      console.log(data)
    })
  }
}

从上面列子可以看到 RxJS 和 Promise 的基本用法非常类似,除了一些关键词不同。 Promise 里面用的是 then() 和 resolve(),而 RxJS 里面用的是 next() 和 subscribe()。

从上面例子我们感觉 Promise 和 RxJS 的用法基本相似。其实 Rxjs 相比 Promise 要强大很多。 比如 Rxjs 中可以中途撤回、Rxjs 可以发射多个值、Rxjs 提供了多种工具函数等等。

2 Rxjs unsubscribe 取消订阅

Promise 的创建之后,动作是无法撤回的。Observable 不一样,动作可以通过 unsbscribe() 方法中途撤回,而且 Observable 在内部做了智能的处理。

java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    // 过一秒撤回
    let stream = this.RequestServiceService.getData()
    let res = stream.subscribe(data => {
      console.log(data)
    })
    setTimeout(() => {
      console.log('取消订阅了')
      res.unsubscribe()
    }, 1000)
  }
}

3 Rxjs 订阅后多次执行

如果我们想让异步里面的方法多次执行,这一点 Promise 是做不到的。对于 Promise 来说,最终结果要么 resolve(兑现)、要么 reject (拒绝),而且都只能触发一次。如果在同一个 Promise 对象上多次调用 resolve 方法, 则会抛异常。而 Observable 不一样,它可以不断地触发下一个值,就像 next() 这个方法的 名字所暗示的那样。

java 复制代码
import {Injectable} from '@angular/core';
import {Observable} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData() {
    return new Observable(observer => {
      setInterval(() => {
        let res = 'zhaoshuai-lc'
        observer.next(res)
      }, 1000)
    })
  }
}
java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    let stream = this.RequestServiceService.getData()
    let res = stream.subscribe(data => {
      console.log(data)
    })
  }
}

4 Angualr6.x 之后使用 Rxjs 的工具函数 map,filter

java 复制代码
import {Injectable} from '@angular/core';
import {Observable} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class RequestServiceService {

  constructor() {
  }

  getData() {
    return new Observable(observer => {
      let count = 0;
      setInterval(() => {
        count++
        observer.next(count)
      }, 1000)
    })
  }
}
java 复制代码
import {Component, OnInit} from '@angular/core';
import {RequestServiceService} from "./services/request-service.service";
import {filter, map} from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(public RequestServiceService: RequestServiceService) {
  }

  ngOnInit(): void {
    let stream = this.RequestServiceService.getData()
    stream.pipe(
      filter(value => Number(value) % 2 == 0),
      map(value => Number(value) * Number(value))
    ).subscribe(data => {
      console.log(data)
    })
  }
}
相关推荐
今日无bug2 分钟前
深入理解 JavaScript 变量提升(Hoisting)
javascript·面试
Csvn7 分钟前
structuredClone:原生深拷贝 API 的正确打开方式
前端
大猫会长11 分钟前
获取favicon.ico的方法
前端·javascript·html
无人生还11 分钟前
从 Vue3 到 React · 快速上手系列第 5 篇:事件处理与表单(受控组件 vs v-model)
前端·vue.js·react.js
默_笙15 分钟前
🎀 大模型说"呀"还是"吗"?temperature 和 Top K 在偷偷控制它的"性格"
前端·javascript
渣波16 分钟前
别再死磕MySQL了!用Milvus+LangChain给AI加个“海马体”,手把手带你写个RAG日记本
前端
乌夷18 分钟前
vue知识点
前端·javascript·vue.js
starrysky81019 分钟前
RuntimeError: dictionary changed size during iteration——多线程 Pydantic cached_property 竞态条件
angular.js
starrysky81020 分钟前
Agent 安全 #06:Agent 灰度发布与回滚 —— 上线新 Prompt 炸了生产,你敢回滚吗?
angular.js
何时梦醒24 分钟前
🚀 从零上手 Milvus 向量数据库:打造一个 AI 智能日记本
前端·人工智能