RxJS - 装载指示器

Max*_*lmo 8 reactive-extensions-js rxjs angularjs

我正在努力探索显示AJAX流的加载指示器的"Rx"方式.

$scope.$createObservableFunction("load")
        .take(1)
        .do(function(){
            $scope.loading = true;
        })
        .flatMap(contentService.AJAX_THINGY_AS_OBSERVABLE)
        .delay(300)
        .subscribe(function(content){
            console.log("content",content);
        },function(error){
            $scope.error = error
        },function() {
            $scope.loading = false;
        });
Run Code Online (Sandbox Code Playgroud)

据我了解,我应该使用.do()副作用,我认为设置loading是,但它不是正确的做事方式.

任何人都可以提供更清洁/更好/适当的如何做到这一点的例子吗?

谢谢!

更新1

我决定把它分成2个流; requestSourceresponseSource.

var loadRequestSource = $scope.$createObservableFunction("load")
    .share();

var loadResponseSource = loadRequestSource
    .flatMap(contentService.AJAX_THINGY_AS_OBSERVABLE)
    .throttle(1000)
    .share();
Run Code Online (Sandbox Code Playgroud)

然后有2个独立的订阅者:

loadRequestSource.subscribe(function () {
    $scope.loading = true;
});

loadResponseSource.subscribe(function (response) {
    /* enter logic */
    $scope.loading = false;
    $scope.$digest();
}, function (err) {
    $scope.error = err;
    $scope.loading = false;
    $scope.$digest();
});
Run Code Online (Sandbox Code Playgroud)

我喜欢这种方法,因为它保持订阅的作用准确.响应用户并不需要关心的设置loadingtrue.它只关心设置它false.

Cal*_*den 2

我喜欢将请求/响应流转换为表示加载属性当前状态的单个流:

const startLoading$ = loadRequestSource.map(() => true);
const stopLoading$ = loadResponseSource.map(() => false);
const loadingState$ = Rx.Observable.merge(startLoading$, stopLoading$);

// Finally, subscribe to the loadingState$ observable
loadingState$.subscribe(state => {
    $scope.$applyAsync(() => $scope.loading = state);
});
Run Code Online (Sandbox Code Playgroud)