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--异步编程的主要内容,如果未能解决你的问题,请参考以下文章
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