ES6 rxjs Observable

2024-03-14 08:32
文章标签 frontend es6 observable rxjs

本文主要是介绍ES6 rxjs Observable,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、拉取(Pull)  、 推送(Push)

介绍 Observable 之前,要先了解两个设计模式:
  • Observer Pattern - (观察者模式)

  • Iterator Pattern - (迭代器模式)

    这两个模式是 Observable 的基础。

Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合。下方表格对Observable进行了定位(为解决基于推送的多值问题):下表是对Observable的使用场景进行的简单的定位。

MagicQ单值多值
拉取(Pull)函数遍历器
推送(Push)PromiseObservable

拉取(Pull) V.S. 推送(Push)

拉取和推送是数据生产者和数据消费者之间通信的两种不同机制。

何为拉取? 在拉取系统中,总是由消费者决定何时从生产者那里获得数据。生产者对数据传递给消费者的时间毫无感知(被动的生产者,主动的消费者)。

JavaScript函数是典型的拉取系统:函数是数据的生产者,对函数进行调用的代码(消费者)从函数调用后的返回值中拉取单值进行消费。

// 函数是数据的生产者
let getLuckyNumber = function() {return 7;
};/* let代码段是数据的消费者,* getLuckyNumber对调用时间毫无感知。 */
let luckNumber = getLuckyNumber();

何为推送? 在推送系统中生产者决定何时向消费者传递数据,消费者对何时收到数据毫无感知(被动的消费者)。

现代JavaScript中Promise是典型的推送系统。作为数据生产者的Promise通过resolve()向数据消费者——回调函数传递数据:与函数不同,Promise决定向回调函数推送值的时间。


MagicQ生产者消费者
拉取被动: 在被请求时产生数据主动: 决定何时请求数据
推送主动: 控制数据的产生逻辑被动: 获得数据后进行响应


二、Observable(被观察者)

实例:首先是创建一个被观察者( observable)。当 observable被订阅后,会立即( 同步地)推送 123 三个值;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() 意味着“不管是同步或者异步,给我一些值”


四、Observable 深度解析

Rx.Observable.createObservable 构造函数的别名,接受一个参数: subscribe函数。

除了使用 create 创建Observable,我们通常还使用 创建操作符 , 如 of from interval , 等来创建Observable。
例:Rx.Observable.of(...)

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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807816

相关文章

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

前端高级CSS用法示例详解

《前端高级CSS用法示例详解》在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交互和动态效果的关键技术之一,随着前端技术的不断发展,CSS的用法也日益丰富和高级,本文将深... 前端高级css用法在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali