angular--异步编程

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了angular--异步编程相关的知识,希望对你有一定的参考价值。

1. 异步编程

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

  • 1、回调函数
  • 2、Promise
  • 3、Rxjs

1.1 准备工作

创建一个asynDemo的项目

ng new asynDemo;

创建一个obtain的服务,并且再app.moudle文件中引入和声明

ng g service services/obtain

创建一个home组件,并且再app.moudle文件中引入和声明

ng g component components/home

现在的项目结构:

在这里插入图片描述

home组件引入和声明obtain服务:

home.component.ts

import {Component, OnInit} from '@angular/core';
// 引入服务
import {ObtainService} from '../../services/obtain.service';

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

  // 初始化服务
  constructor(public obtain: ObtainService) {
  }

  ngOnInit(): void {
  }

}

把app.component.html里面的内容替换为

<app-home></app-home>

1.2 不处理异步


1.2.1 同步方法(获取数据没有问题)

在obtain服务中声明方法:

  public getDate(): any {
    return 'this is a data';
  }

在home组件中调用方法

  ngOnInit(): void {
    let data = this.obtain.getDate();
    console.log('data: ' + data);
  }

在这里插入图片描述


1.2.2 异步方法(获取数据有问题: undefined)

在obtain服务中声明方法:

  public getCallbackData(): any {
    //执行顺序
    // 第一步: 定时器前面的代码
    // ...
    // 第二步: 定时器(定时器是一个异步方法)
    setTimeout(() => {
      // 第四步: 定时器内部的代码
      let name = '长安';
      return name;
    }, 1000);
    // 第三步: 定时器后面的代码
    // ...
  }

在home组件中调用方法

  ngOnInit(): void {
    let data = this.obtain.getCallbackData();
    console.log('data: ' + data);
  }

在这里插入图片描述


1.3 处理异步


1.3.1 回调函数处理异步

在obtain服务中声明方法:

  // 回调函数处理异步
  public getCallbackData(getDate): any {
    //执行顺序
    // 第一步: 定时器前面的代码
    // ...
    // 第二步: 定时器(定时器是一个异步方法)
    setTimeout(() => {
      // 第四步: 定时器内部的代码
      let name = '长安';
      getDate(name);
    }, 1000);
    // 第三步: 定时器后面的代码
    // ...
  }

在home组件中调用方法

  ngOnInit(): void {
    this.obtain.getCallbackData((date) => {
      console.log('data: ' + date);
    });
  }

在这里插入图片描述


1.3.2 Promise处理异步

在obtain服务中声明方法:

  // Promise处理异步
  getPromiseData() {
    // resolve表示异步任务成功的回调函数, reject表示异步任务失败的回调函数(可以省略)
    return new Promise((resolve, reject) => {  
      setTimeout(() => {
        let username = '张三--Promise';
        // 通过resolve()函数返回数据
        resolve(username);
      }, 3000);
    });
  }

在home组件中调用方法

  ngOnInit(): void {
    // 通过Promise里面的then()函数获取异步的数据
    this.obtain.getPromiseData().then(data => {
      console.log('data: ' + data);
    });
  }

在这里插入图片描述


1.3.3 Rxjs处理异步

在obtain服务中声明方法:

import {Observable} from 'rxjs'; 

  // rxjs处理异步
  getRxjsData() {
    return new Observable(observer => {
      setTimeout(() => {
        let username = '张三--Rxjs';
        // 异步任务成功时返回的数据
        observer.next(username);
        // 异步任务失败时返回的数据 一般忽略
        observer.error('error');
      }, 3000);
    });
  }

在home组件中调用方法

  ngOnInit(): void {
    // 通过subscribe() 订阅 来获取异步数据
    this.obtain.getRxjsData().subscribe(data => {
      console.log(data);
    });
  }

在这里插入图片描述


1.3.4 Promise和Rxjs的区别

  • RxJS 和 Promise 的基本用法非常类似,除了一些关键词不同。Promise 里面用的是 then() 和 resolve(),而 RxJS 里面用的是 next() 和 subscribe()。
  • 觉Promise 和 RxJS 的用法基本相似。其实Rxjs相比Promise 要强大很多。 比如 Rxjs 中可以中途撤回、Rxjs 可以发射多个值、Rxjs 提供了多种工具函数等等。

1.4 Rxjs功能探究


1.4.1 Rxjs unsubscribe 取消订阅

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

在obtain服务中声明方法:

  // rxjs处理异步
  getRxjsData() {
    return new Observable(observer => {
      setTimeout(() => {
        let username = '张三--Rxjs';
        // 成功时返回的数据 3s后返回数据
        observer.next(username);
        // 失败时返回的数据 一般忽略
        observer.error('error');
      }, 3000);
    });
  }

在home组件中调用方法: 过一秒以后撤回操作

  ngOnInit(): void {
    // 通过subscribe() 订阅 来获取异步数据
    let stream = this.obtain.getRxjsData().subscribe(data => {
      console.log(data);
    });

    // 定时器 1s以后取消订阅
    setTimeout(() => {
      stream.unsubscribe();
    }, 1000);
  }

在这里插入图片描述


1.4.2 Rxjs 订阅后多次执行

  • 如果我们想让异步里面的方法多次执行,比如下面代码。 这一点 Promise 是做不到的,对于 Promise 来说,最终结果要么 resole(兑现)、要么 reject (拒绝),而且都只能触发一次。如果在同一个 Promise 对象上多次调用 resolve 方法, 则会抛异常。而 Observable 不一样,它可以不断地触发下一个值,就像 next() 这个方法的 名字所暗示的那样。
  • 比如我们有一个异步方法:每隔2s返回一次数据,如果使用回调函数和Promise来处理,那么只可以得到第一次返回的数据,但是Rxjs可以得到多次数据

在obtain服务中声明方法:

  getRxjsIntervalData() {
    let count = 0;
    return new Observable<any>((observer) => {
      // 每隔2s返回一次数据
      setInterval(() => {
        let username = '张三--Rxjs-Interval' + (++count);
        observer.next(username);
      }, 1000);
    });
  }

在home组件中调用方法:

  ngOnInit(): void {
    this.obtain.getRxjsIntervalData().subscribe(data => {
      console.log('data: ' + data);
    });
  }

在这里插入图片描述


1.4.3 Rxjs 的工具函数 map filter

  • map(): 对数据进行处理。
  • filter(): 对数据进行过滤。

在obtain服务中声明方法:

  // 每个0.5s返回一个自增1的数据
  getRxjsIntervalNum() {
    let count = 0;
    return new Observable<any>((observer) => {
      setInterval(() => {
        observer.next(count++);
      }, 500);
    });
  }

在home组件中调用方法:


1.filter()

筛选出偶数的数据

import {filter, map} from 'rxjs/operators';

  ngOnInit(): void {
    // pipe() 管道: 用管道来处理数据
    this.obtain.getRxjsIntervalNum().pipe(filter((data) => {
      // 返回偶数的数据
      return data % 2 == 0;
    })).subscribe(data => {
      console.log('data: ' + data);
    });
  }

在这里插入图片描述


map()

返回数据的平方

import {filter, map} from 'rxjs/operators';

  ngOnInit(): void {
    // pipe() 管道: 用管道来处理数据
    this.obtain.getRxjsIntervalNum().pipe(map((data) => {
      // 返回数据的平方
      return data * data;
    })).subscribe(data => {
      console.log('data: ' + data);
    });
  }

在这里插入图片描述


map() & filter()

返回偶数数据的平方

import {filter, map} from 'rxjs/operators';

  ngOnInit(): void {
    // pipe() 管道: 用管道来处理数据
    this.obtain.getRxjsIntervalNum().pipe(filter((data) => {
      // 返回偶数(过滤掉奇数)
      return data % 2 == 0;
    }), map((data) => {
      // 返回数据的平方
      return data * data;
    })).subscribe(data => {
      console.log('data: ' + data);
    });
  }

在这里插入图片描述



以上是关于angular--异步编程的主要内容,如果未能解决你的问题,请参考以下文章

使用Task.Wait而不是等待异步编程

json 可视代码工作室Angular with Firebase片段

typescript Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming/angular-2/

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming