Angular 7的可观察性
观察者为angular应用程序中的发布者和订阅者之间的数据共享提供支持。与承诺等技术相比,它被称为是一种更好的事件处理、异步编程和处理多值的技术。
观察者的一个特点是,它只能由订阅它的消费者访问,即定义了一个发布数值的函数,但它不会被订阅的消费者执行(它可以是任何组件),只有通过这个函数,客户才能收到通知,直到该函数运行或直到他们订阅。
一个可观察变量可以传递任何类型的多个值。在任何情况下,接收值的API都是一样的,设置和逻辑都由可观察器处理。剩下的事情只是关于订阅和取消订阅所需的信息。
观察者:为了处理接收可观察的消息,我们需要一个可观察的接口,它由与可观察的消息有关的回调方法组成。其中一些基本方法如下。
- 下一个。它是可观察到的每个消息的处理程序,它可以在执行开始后被调用零次或多次。
例子:这是一个关于观察者的next()方法用法的简单例子。
import { Component, OnInit } from '@angular/core';
import {Observable} from 'rxjs';
@Component({
selector: 'app-next-example',
templateUrl: './next-example.component.html',
styleUrls: ['./next-example.component.css']
})
export class NextExampleComponent implements OnInit {
constructor() { }
ngOnInit() {
// Create a new Observable
const sqnc = new Observable(countOnetoTen);
// Execute the Observable and print the
// result of each notification
// next() is a call to countOnetoTen method
// to get the next value from the observable
sqnc.subscribe({
next(num) { console.log(num); }
});
// This function runs when subscribe()
// is called
function countOnetoTen(observer) {
for(var i = 1; i <= 10; i++) {
// Calls the next observable
// notification
observer.next(i);
}
// Unsubscribe after completing
// the sequence
return {unsubscribe(){}};
}
}
}
- 输出:
- 错误。它是每个错误信息的处理程序。一个错误会停止对可观察实例的执行。
例子:这是一个例子,在代码中故意诱发错误,以了解错误的工作原理。
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-error-example',
templateUrl: './error-example.component.html',
styleUrls: ['./error-example.component.css']
})
export class ErrorExampleComponent implements OnInit {
constructor() { }
ngOnInit() {
// Create a new Observable
const sqnc = new Observable(generateError);
// Execute the Observable and print the
// result of each notification
// error() is called when next generate
// some error
sqnc.subscribe({
next(num) { },
error(err) { console.log('Error Somewhere')}
});
// This function runs when subscribe() is called
function generateError(observer){
// Calls the next observable notification
// It generates an error and error is called
observer.next( adddlert("Welcome guest!"));
// Unsubscribe after completing the sequence
return {unsubscribe(){}};
}
}
}
- 输出:
- 完成。它是通知可观察到的执行完成的句柄。
例子:这个例子展示了完整函数的使用。完成通知是在观察者完成对可观察对象的执行后触发的。
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-complete-example',
templateUrl: './complete-example.component.html',
styleUrls: ['./complete-example.component.css']
})
export class CompleteExampleComponent implements OnInit {
constructor() { }
ngOnInit() {
// Create a new Observable
const sqnc = new Observable(countOnetoTen);
// Execute the Observable and print the
// result of each notification
sqnc.subscribe({
next(num) { console.log(num); },
complete(){console.log("Completed!!!!")}
});
// This function runs when subscribe()
// is called
function countOnetoTen(observer){
for(var i = 1; i <= 10; i++) {
// Calls the next observable
// notification
observer.next(i);
}
observer.complete();
// Unsubscribe after completing
// the sequence
return {unsubscribe(){}};
}
}
}
- 输出:
制作一个可观察变量:在下面的例子中,我们将制作一个简单的可观察变量,用于获取一个2的表格。在使用Observables之前,先从rxjs库中导入Observables,写下以下代码。
import {Observables} from 'rxjs'
import { Component } from '@angular/core';
import {Observable} from "rxjs";
import { CompileTemplateMetadata } from '@angular/compiler';
@Component({
selector: 'app-rt',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'MyFirstApp';
}
// Create a new Observable that will
// deliver the above sequence
const table = new Observable(tableOfTwo);
// Execute the Observable and print the
// result of each notification
// next() is a call to tableOfTwo() method
// to get the next value from the observable
table.subscribe({
next(num) { console.log(num); },
complete() { console.log('Finished sequence'); }
});
// This function runs when subscribe() is called
function tableOfTwo(observer) {
for(var i = 1; i <= 10; i++) {
observer.next('2 * ' + i + ' = ' + i*2);
}
observer.complete();
return {unsubscribe(){}};
}
在这段代码中,next()被用来调用观测器的下一个返回,在观测器中,任务完成后,它返回unsubscribe函数,导致观测器的取消订阅,因此不能再进行请求。当complete()方法被调用时,它会打印出字符串 “完成序列”。所有的功能都显示在控制台中。
输出:
多播:它是一种在一次执行中向多个订阅者列表广播一个可观察的做法。使用多播观测器,不需要在文件上注册多个监听器,而是重复使用第一个监听器,并将值发送给每个订阅者。它是通过确定观察者关于值是否要被多播来完成的。
继续上面的例子,现在将进行组播操作,它将在两个2的序列上投出同一个表,并在做另一个操作之前等待一秒钟。
import { Component, OnInit } from '@angular/core';
import {Observable} from 'rxjs';
@Component({
selector: 'app-my-page',
templateUrl: './my-page.component.html',
styleUrls: ['./my-page.component.css']
})
export class MyPageComponent implements OnInit {
constructor() { }
ngOnInit() {
const multiSeq = new Observable(this.multiSeqSubs());
multiSeq.subscribe({
next(num) { console.log('1st subscribe: ' + num); },
complete() { console.log('1st sequence finished.'); }
});
// Subscribe again After 1 seconds.
setTimeout(() => {
multiSeq.subscribe({
next(num) { console.log('2nd subscribe: ' + num); },
complete() { console.log('2nd sequence finished.'); }
});
}, 1000);
}
multiSeqSubs() {
const seq = [];
for (var i = 1; i <= 10; i++) {
// Pushes the string onto sequence
seq.push('2 * ' + i + '=' + 2*i)
}
// Keep track of each observer
const obs = [];
// A single time Stamp for one
// set of values being generated,
// multicasted to each subscriber
let timeStamp;
// Return the subscriber function
// (runs when subscribe() function
// is invoked)
return (ob) => {
obs.push(ob);
// When this is the first subscription,
// start the sequence
if (obs.length === 1) {
timeStamp = this.exec_Sequence({
next(val) {
// Iterate through observers
// and notify all subscriptions
obs.forEach(o => o.next(val));
},
complete() {
// Notify all complete callbacks
obs.slice(0).forEach(o => o.complete());
}
}, seq, 0);
}
return {
// Unsubscribe from the observers
unsubscribe() {
obs.splice(obs.indexOf(ob), 1);
// Cleanup
if (obs.length === 0) {
clearTimeout(timeStamp);
}
}
};
};
}
// Executes the sequence
exec_Sequence(observer, sequence, index) {
return setTimeout(() => {
observer.next(sequence[index]);
if (index === sequence.length - 1) {
observer.complete();
} else {
this.exec_Sequence(observer, sequence, ++index);
}
}, 1000);
}
// Create a new Observable that will
// deliver the above sequence
}
这段代码正在做同样的功能,即处理组播操作。在这段代码中,我们有一个观察者列表,它取决于对组播操作的订阅数量。在代码执行过程中,我们只有2个操作在执行,因此我们在’obs’列表中只有2个元素。
输出:
Error Handling:
观察者产生异步值,因此try/catch不能捕捉任何错误,因为它可能导致代码停止,而不考虑在该时间点运行的其他任务。相反,我们通过在观测器上指定一个错误回调来处理错误。当产生错误时,它会导致观察者清理订阅并停止为该订阅产生值。观察者既可以产生值(调用下一个回调),也可以完成,调用完成或错误回调。
错误回调的语法
observable.subscribe({
next(val) { console.log('Next: ' + val)},
error(err) { console.log('Error: ' + err)}
});