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

相关文章

spring-boot-starter-thymeleaf加载外部html文件方式

《spring-boot-starter-thymeleaf加载外部html文件方式》本文介绍了在SpringMVC中使用Thymeleaf模板引擎加载外部HTML文件的方法,以及在SpringBoo... 目录1.Thymeleaf介绍2.springboot使用thymeleaf2.1.引入spring

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element