首页 文章

RxJs从结果Promise中创建Observable

提问于
浏览
8

我是RxJs的新手,我想了解与Rx结合使用Rx的最佳方法 .

我想要创建的是Angular中的一项服务,它充当事件调度程序模式,并在承诺完成后发出事件 . 我还需要的是,如果没有(事件)订阅者,则observable永远不会被调用 . 我想要发生的最后一件事是observable的任何后续订阅者获得相同的结果而不会触发对服务器的另一个请求 . 我已经设法在这里实现我自己的解决方案:

// ... CountryService code

var COUNTRIES_LOADED = Rx.Observable
    .create(function (observer) {
        $http
            .get('/countries')
            .then(function (res) {
                observer.onNext(res);
            }, function (err) {
                observer.onError(err);
            })
            .finally(function () {
                observer.onCompleted();
            });
    })
    .shareReplay();

现在,只要我订阅了一个新的“监听器”来对象,就会被拉出来 . 任何新订阅者都将获得缓存的值,而无需再次触及服务器 .

所以在我的“消费者”(Angular Directive)中,我想做这样的事情:

// ... countryInput directive code:

COUNTRIES_LOADED.subscribe(function (response) {
    // Fill in countries into scope or ctrl
    scope.countries = response.countries;
});

COUNTRIES_LOADED观察者的任何未来订阅者都不得触发$ http请求 . 同样,如果指令从未包含在页面中,则永远不会调用$ http .

上面的解决方案有效,但我不知道这种方法的潜在缺点和内存含义 . 这是有效的解决方案吗?有没有更好/更合适的方法来实现这个使用RxJs?

非常感谢!

4 回答

  • 4

    使用 Rx.Observable.fromPromise(promise)

    fromPromise:

    转换符合Promise / A规范的Promise和/或符合ES2015的Promise或将所述Promise返回到Observable序列的工厂函数 .

    example:

    var source = Rx.Observable.fromPromise(promise);
    
    var subscription = source.subscribe(
      function (x) {
        console.log('Next: %s', x);
      },
      function (err) {
        console.log('Error: %s', err);
      },
      function () {
        console.log('Completed');
      });
    
  • 2

    我在这里找到了答案(略有不同的名字)rxjs using promise only once on subscribe

    所以对于我的例子,答案很简单:

    var loadCountries = function () { return $http.get('/countries'); };
    
    var observable = Rx.Observable.defer(loadCountries).shareReplay();
    
  • 5

    您是否尝试使用 rxjs5fromPromise() API?

    检查它的文档here

  • 1

    这是你如何使用Observables让我们说你有一个名为 getuser(username) 的方法 .

    //Returns an observable
    getUser(username){
        return $http.get(url)
            .map(res => res.json());
    }
    

    你可以使用它如下

    getUser.subscribe(res => console.log(response));
    

    但是如果你想使用promises

    //Returns an Promise
    //Donot forget to import toPromise operator
    getUser(username){
        return $http.get(url)
            .map(res => res.json())
            .toPromise();
    }
    

    你可以使用它如下

    getUser.then(res => console.log(response));
    

相关问题