本文主要是介绍ES6 rxjs Observable,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、拉取(Pull) 、 推送(Push)
Observer Pattern - (观察者模式)
- Iterator Pattern - (迭代器模式)
这两个模式是 Observable 的基础。
Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合。下方表格对Observable进行了定位(为解决基于推送的多值问题):下表是对Observable
的使用场景进行的简单的定位。
MagicQ | 单值 | 多值 |
---|---|---|
拉取(Pull) | 函数 | 遍历器 |
推送(Push) | Promise | Observable |
拉取(Pull) V.S. 推送(Push)
拉取和推送是数据生产者和数据消费者之间通信的两种不同机制。
何为拉取? 在拉取系统中,总是由消费者决定何时从生产者那里获得数据。生产者对数据传递给消费者的时间毫无感知(被动的生产者,主动的消费者)。
JavaScript函数是典型的拉取系统:函数是数据的生产者,对函数进行调用的代码(消费者)从函数调用后的返回值中拉取单值进行消费。
// 函数是数据的生产者
let getLuckyNumber = function() {return 7;
};/* let代码段是数据的消费者,* getLuckyNumber对调用时间毫无感知。 */
let luckNumber = getLuckyNumber();
何为推送? 在推送系统中生产者决定何时向消费者传递数据,消费者对何时收到数据毫无感知(被动的消费者)。
现代JavaScript中Promise是典型的推送系统。作为数据生产者的Promise通过resolve()
向数据消费者——回调函数传递数据:与函数不同,Promise决定向回调函数推送值的时间。
MagicQ | 生产者 | 消费者 |
---|---|---|
拉取 | 被动: 在被请求时产生数据 | 主动: 决定何时请求数据 |
推送 | 主动: 控制数据的产生逻辑 | 被动: 获得数据后进行响应 |
observable
被订阅后,会立即( 同步地)推送 1
, 2
, 3
三个值;1秒之后,继续推送 4
这个值,最后结束( 推送结束通知):
var observable = Rx.Observable.create(function (observer) {observer.next(1);observer.next(2);observer.next(3);setTimeout(() => {observer.next(4);observer.complete();}, 1000);
});
为得到observable
推送的值,我们需要订阅(subscribe)这个Observable:(通过.subscribe这个方法进行订阅行为)
var observable = Rx.Observable.create(function (observer) { // 此处是创建一个被观察者observableobserver.next(1);observer.next(2);observer.next(3);setTimeout(() => {observer.next(4);observer.complete();}, 1000);
});console.log('just before subscribe');
observable.subscribe({ // 此处是对observable 进行订阅,即创建一个观察者observenext: x => console.log('got value ' + x),error: err => console.error('something wrong occurred: ' + err),complete: () => console.log('done'),
});
console.log('just after subscribe');
程序执行后,将在控制台输出如下结果:
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done
三、Observable 是函数概念的拓展
Observable 更像是一个不需要传入参数的函数,它拓展了函数的概念使得它可以返回多个值。
看看下面的例子:
function foo() {console.log('Hello'); return 42;
}console.log('before');
console.log(foo.call()); // foo.call()等同于直接掉用foo()
console.log('after');
"before"
"Hello"
42
"after"
Observable的行为完全一样:
var foo = Rx.Observable.create(function (observer) { console.log('Hello'); observer.next(42);
});console.log('before');foo.subscribe(function (x) { console.log(x);
});console.log('after');
"before"
"Hello"
42
"after"
订阅 foo
完全是同步的,与函数的调用一样。
Observable可以异步或者同步地产生数据。
那Observable 与函数的不同之处在哪里? Observable可以在一个时间过程中‘返回’多个值,而函数却不能。在函数中你不可以这么做:
function foo() {console.log('Hello');return 42;return 100; // 这个语句永远不会被执行。
}
虽然函数只能有一个返回值,但是在Observable中你完全可以这么做:
var foo = Rx.Observable.create(function (observer) {console.log('Hello');observer.next(42);observer.next(100); // 返回另一个值observer.next(200); // 返回另一个值
});console.log('before');
foo.subscribe(function (x) {console.log(x);
});
console.log('after');
输出结果如下:
"before"
"Hello"
42
100
200
"after"
你甚至可以异步地返回值:
var foo = Rx.Observable.create(function (observer) {console.log('Hello');observer.next(42);observer.next(100);observer.next(200);setTimeout(() => {observer.next(300); // happens asynchronously}, 1000);
});console.log('before');
foo.subscribe(function (x) {console.log(x);
});
console.log('after');
输出结果:
"before"
"Hello"
42
100
200
"after"
300
结论:
func.call()
意味着“同步地给我一个值”observable.subscribe()
意味着“不管是同步或者异步,给我一些值”
Rx.Observable.create
是 Observable
构造函数的别名,接受一个参数: subscribe
函数。
create
创建Observable,我们通常还使用 创建操作符 , 如 of
, from
, interval
, 等来创建Observable。 Observable在执行过程中,可以推送三种类型的值:
"Next" 通知: 实际产生的数据,包括数字、字符串、对象等
"Error" 通知:一个JavaScript错误或者异常
- "Complete" 通知:一个不带有值的事件“Next” 通知是最重要和常用的类型:表示事件传递给观察者的数据。错误和完成通知仅会在执行阶段推送其一,并不会同时推送错误和完成通知。
在Observable的执行过程中,0个或者多个“Next”通知会被推送。在错误或者完成通知被推送后,Observable不会再推送任何其他通知。
下面代码展示了Observable 在执行过程中推送3个“Next” 通知然后结束:
var observable = Rx.Observable.create(function subscribe(observer) {observer.next(1);observer.next(2);observer.next(3);observer.complete();
});
Observable 严格遵守 Observable 契约,后面值为4
的“Next” 通知永远不会被推送:
var observable = Rx.Observable.create(function subscribe(observer) {observer.next(1);observer.next(2);observer.next(3);observer.complete();observer.next(4); // 由于违法契约,4不会被推送
});
使用try
/catch
块包裹 subscribe
代码是一个很赞的想法,如果捕获了异常,可以推送错误通知:
var observable = Rx.Observable.create(function subscribe(observer) {try {observer.next(1);observer.next(2);observer.next(3);observer.complete();} catch (err) {observer.error(err); // 捕获异常后推送错误通知}
});
这篇关于ES6 rxjs Observable的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!