65.9K
CodeProject 正在变化。 阅读更多。
Home

关于 RxJS Subjects 的说明

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2017 年 7 月 2 日

CPOL

4分钟阅读

viewsIcon

10230

downloadIcon

74

这是一篇关于 RxJS Subject 的注意事项。

引言

这是一篇关于 RxJS Subject 的注意事项。

背景

基于组件的编程在 Web 应用中越来越受欢迎。无论您是使用 React 还是 Angular,或者您选择不使用任何框架,RxJS Subject 都可以用于不同编程单元之间的通信。

RxJS Subject 是一个 JavaScript 对象,它可以将通知广播给来自任何发布者的所有订阅者。

除了给出一些简单的例子,本篇注意事项还讨论了如何在 Subject 广播错误后保持 RxJS Subject 的活跃。

附件是一个 Maven 项目,包含三个小程序。但您不需要 Java 就可以运行它。所有示例都在 HTML 文件中。您可以将 HTML 文件托管在任何 Web 服务器上。

RxJS 的基本示例

让我们先来看一下“rxjs-1-basic-example.html”。RxJS Subject 非常容易使用。为了节省我描述 RxJS Subject 用法的精力,我建议您在查看示例之前,先快速浏览一下 RxJS 文档

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>rxjs-1-basic-example.html</title>
<link rel="stylesheet" type="text/css" href="styles/app.css">
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
    
<script type="text/javascript">
        
    let ClockSubject = new Rx.BehaviorSubject('');
        
    let SubscribeToClockSubject = function(eId) {
        let element = document.getElementById(eId);
            
        ClockSubject.subscribe(
            function(time) {
                element.innerHTML = time;
            },
            function(error) {
                element.innerHTML = error;
            }
        );
    };
        
    window.onload = function() {
        SubscribeToClockSubject('clock1');
        SubscribeToClockSubject('clock2');
        SubscribeToClockSubject('clock3');
            
        let getTime = function() {
            let d = new Date();
                
            return d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
        };
            
        // Set a timer to update the subject
        setInterval(function() {
            ClockSubject.next(getTime());
            
        }, 1000);
        
        // Set the subject at page load
        ClockSubject.next(getTime());
    };
    
</script>
    
</head>
<body>
<div><a href="index.html">Back ...</a></div>
<div id="clock1" class="clock"></div>
<div id="clock2" class="clock"></div>
<div id="clock3" class="clock"></div>
</body>
</html>

在这个示例中,我在 HTML 中添加了三个“div”。目标是在所有“div”中显示当前时间。每秒钟使用“setInterval”回调来获取当前时间。它通过一个名为“ClockSubject”的 RxJS Subject 发送到所有订阅者。

  • 发布者可以通过 Subject 上的“next()”方法向所有订阅者发布通知;
  • 发布者可以通过 Subject 上的“error()”方法向所有订阅者发布错误(我们将在第二个示例中看到“error()”的示例)。

当我们订阅 RxJS 对象时,我们可以将两个回调函数传递给“subscribe()”方法。

  • 第一个函数是通知回调函数。当发布通知时,会调用此函数;
  • 第二个函数是错误回调函数。当发布错误时,会调用此函数。

如果我们把“rxjs-1-basic-example.html”加载到浏览器中,可以看到时间在所有“div”中显示并每秒钟持续更新。所有订阅者都通过“ClockSubject”接收到“ClockSubject.next(getTime())”发布的当前时间通知数据。

哎呀 - 错误是个问题?

为了保持第一个示例的简单性,我们没有尝试错误通知。但是错误确实会发生,并且有必要将错误通知发布给订阅者。现在让我们来看一下“rxjs-2-error-example.html”。

let i = 0;
        
// Set a timer to update the subject
setInterval(function() {
    if (++i == 5) {
        i = 0;
        ClockSubject.error('An artificial error!');
        return;
    }
            
    ClockSubject.next(getTime());
            
}, 1000);

为了测试错误通知,我每隔五秒钟人为地广播一次错误通知。

ClockSubject.subscribe(
    function(time) {
        element.innerHTML = time;
    },
    function(error) {
        element.innerHTML = error;
    }
);

如果订阅者收到通知,“div”将显示时间。如果收到错误,“div”将显示错误消息。

如果我们把“rxjs-2-error-example.html”加载到浏览器中,我们可以看到时间被显示和更新。但是当收到错误时,整个网页就停止了。任何进一步的时间更新都无效了。

错误是个问题

根据这个链接,错误是个问题。对 Subject 的任何“error()”调用基本上都会杀死该 Subject。它不再活跃,并且停止广播任何进一步的通知或错误。在这个示例中,在第一次调用“ClockSubject.error('An artificial error!')”之后,任何“ClockSubject.next(getTime())”都不会发送给订阅者。

RxJS Subject 的包装器

在许多情况下,我们确实希望 Subject 在广播错误后仍然保持活跃。为了保持 Subject 的活跃,我在“rxjs-3-error-handle-example.html”中创建了一个简单的包装器 Subject。

// Wrapper of a Subject that does not stop on Error notification
Rx.FullSubject = function() {
    let self = this;
        
    let nSubject = new Rx.Subject();
    let eSubject = new Rx.Subject();
        
    self.subscribe = function(ns, es) {
        nSubject.subscribe(ns);
        eSubject.subscribe(es);
    };
        
    self.next = function(value) {
        nSubject.next(value);
    }
        
    self.error = function(error) {
        eSubject.next(error);
    }
}

FullSubject”有两个 RxJS Subject

  • nSubject”负责广播通知
  • eSubject”负责广播错误

eSubject”使用“next()”方法而不是“error()”方法来广播错误。发送错误后,“eSubject”仍然是活跃的,因此“FullSubject”仍然是活跃的。

let ClockSubject = new Rx.FullSubject();

如果我们把“rxjs-3-error-handle-example.html”加载到浏览器中,我们可以看到当发送错误时,错误消息会显示在“divs”中。

但是当发送时间通知时,“divs”中会显示当前时间。“FullSubject”在发送错误消息后保持活跃。

关注点

  • 这是一篇关于 RxJS Subject 的注意事项;
  • RxJS Subject 是一个 JavaScript 对象,它可以将通知广播给来自任何发布者的所有订阅者;
  • RxJS Subject 可能有助于 React 或 Angular 组件之间的通信;
  • 希望您喜欢我的博文,并希望这篇笔记能以某种方式帮助您。

历史

  • 2017/7/3:首次修订
© . All rights reserved.