Why RxJS?

你可能会问,为什么选择 RxJS? 为什么不是 Promises? Promises 可以很好地解决异步操作,像使用 XMLHttpRequest 去查询服务器, 它预期会返回值并且最终完成请求。 The Reactive Extensions 统一了 JavaScript 中的 Promises, callbacks 以及事件数据,比如 DOM输入, Web Workers, Web Sockets. 一旦我们统一了这些概念,就可以进行各种各样的组合.

为了让您了解丰富的组合,我们可以创建一个自动完成功能,它从文本输入中接收用户输入,然后查询服务,确保不会对每个键盘输入的进行泛滥地调用,而是以一种更自然的方式调用。

首先,我们将引用JavaScript文件,包括jQuery,尽管RxJS没有依赖于jQuery ...

<script src="http://code.jquery.com/jquery.js"></script>
<script src="rx.lite.js"></script>

接下来,我们将从输入框获取用户输入,使用Rx.Observable.fromEvent 方法监听 keyup 事件. 如果 jQuery, Zepto, AngularJS and Ember.js 可用,将会使用它们来绑定事件, 否则将使用原生事件绑定. 这跟您的框架思考事件的一致方式,因此没有任何惊喜。

var $input = $('#input'),
    $results = $('#results');

/* 只从 keyup 事件获得输入值 */
var keyups = Rx.Observable.fromEvent($input, 'keyup')
    .map(e => e.target.value)
    .filter(text => text.length > 2);

/* 函数节流输出设置为 500ms */
var throttled = keyups.throttle(500 /* ms */);

/* 现在判断值是否有改变,只获取不同的值 */
var distinct = throttled.distinctUntilChanged();

现在,让我们来查询维基百科!在RxJS中,我们可以立即通过Rx.Observable.fromPromise方法绑定到任何Promises A+的实现上,或者直接返回它,并将其封装。

function searchWikipedia (term) {
    return $.ajax({
        url: 'http://en.wikipedia.org/w/api.php',
        dataType: 'jsonp',
        data: {
            action: 'opensearch',
            format: 'json',
            search: term
        }
    }).promise();
}

一旦创建,现在我们可以将不同的节流输入绑定在一起,然后查询服务。在这种情况下,我们将调用flatMapLatest获取该值,并确保我们不会有任何混乱的调用。

var suggestions = distinct.flatMapLatest(searchWikipedia);

最后,我们将在可观察对象上调用subscribe方法开始拉数据。

suggestions.subscribe(data => {
    var res = data[1];

    /* Do something 像数据绑定 */
    $results.empty();

    $.each(res, (_, value) => $('<li>' + value + '</li>').appendTo($results));
}, error => {
    /* handle any errors */
    $results.empty();

    $('<li>Error: ' + error + '</li>').appendTo($results);
});