Why RxJS?
我们可能会问自己,为什么使用RxJS?不是有Promise吗?没错,Promise对于只期望单值返回的异步请求(比如:XMLHttpRequest)是一个好的解决方案。但Reactive Extensions for JavaScript对Promises, callbacks , Web Workers, Web Sockets进行了统一优化. 一旦我们统一优化这一些概念后,我们将能更好的进行开发。
为了更好的理解,我们可以创建一个autocompletion 的例子。在该例子中用户在text input中输入值,然后AJAX通过这一些值查询出相关的信息,同时还要避免频繁的进行AJAX查询而影响性能。
首先,我们引入JQuery和RxJS文件。注意:RxJS不依赖于JQuery。
<script src="http://code.jquery.com/jquery.js"></script>
<script src="rx.lite.js"></script>
接下来,我们将从input标签获得用户输入的值,然后通过Rx.Observable.fromEvent
方法监听keyup事件。 如果需要,我们也可以通过jQuery, Zepto, AngularJS and Ember.js进行事件绑定。
var $input = $('#input'),
$results = $('#results');
/* Only get the value from each key up */
var keyups = Rx.Observable.fromEvent($input, 'keyup')
.map(e => e.target.value)
.filter(text => text.length > 2);
/* Now throttle/debounce the input for 500ms */
var throttled = keyups.throttle(500 /* ms */);
/* Now get only distinct values, so we eliminate the arrows and other control characters */
var distinct = throttled.distinctUntilChanged();
现在,让我们来查查Wikipedia! 在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();
}
一旦创建完成,我么可以配合distinc输入,然后查询。在该例子中,我们将调用flatMapLatest
去得到值,并且确保我们不会被其他有序序列(order sequence)调用。
var suggestions = distinct.flatMapLatest(searchWikipedia);
最后,我们将在我们的可观察序列(observable sequence)中通过subscribe 方法通拉取数据。
suggestions.subscribe(data => {
var res = data[1];
/* Do something with the data like binding */
$results.empty();
$.each(res, (_, value) => $('<li>' + value + '</li>').appendTo($results));
}, error => {
/* handle any errors */
$results.empty();
$('<li>Error: ' + error + '</li>').appendTo($results);
});