1 目前常见的异步编程的几种方法
首先给出一个异步请求的实例:
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RequestServiceService {
constructor() {
}
getData() {
setTimeout(() => {
let res = 'zhaoshuai-lc'
return res
}, 3000)
}
}
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 回调函数解决问题
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)
})
}
}
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 处理异步
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)
})
}
}
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 处理异步
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)
})
}
}
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 在内部做了智能的处理。
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() 这个方法的 名字所暗示的那样。
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)
})
}
}
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
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)
})
}
}
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)
})
}
}