将observable返回给调用者函数,如返回promises

时间:2017-04-03 08:12:48

标签: angular angular2-observables

我目前正从角度1.x迁移到角度2。该应用程序目前遵循John Papa的风格指南Return a Promise from Data Calls

activate();

function activate() {
    /**
     * Step 1
     * Ask the getAvengers function for the
     * avenger data and wait for the promise
     */
    return getAvengers().then(function() {
        /**
         * Step 4
         * Perform an action on resolve of final promise
         */
        logger.info('Activated Avengers View');
    });
}

function getAvengers() {
      /**
       * Step 2
       * Ask the data service for the data and wait
       * for the promise
       */
      return dataservice.getAvengers()
          .then(function(data) {
              /**
               * Step 3
               * set the data and resolve the promise
               */
              vm.avengers = data;
              return vm.avengers;
      });
}

我如何用Observables做同样的事情?有了承诺,我可以在多个函数中编写.then()并返回它,这样调用函数也会等待承诺。但有了可观察性,做正确的事情是什么?
我应该在哪里订阅,我应该在哪里映射值并返回可观察量?

3 个答案:

答案 0 :(得分:1)

当您想要修改发送的数据时,应使用

map,并通过这样做来创建新的Observable

实施例

getAvengers.map(avengers => avengers.forEach(a => a.kill))将创建一个可观察的死亡复仇者。然后你可以订阅这个observable来调用死亡复仇者的方法。

subscribe更像then,因为它只是等待数据调用传递给它的方法。但是订阅会触发可观察对象,这意味着如果您只是致电getAvengers()(假设getAvengers返回Observable),您将获得Observable,以触发请求必须subscribe

要小心:

两次调用subscribe会触发Observable两次,这意味着如果您根据http请求在subscribe上调用Observable,则请求将完成两次。

因此,您可以使用带有observable的缓存来处理此问题,但文档将能够指导您完成此操作。

答案 1 :(得分:1)

假设您的函数在执行http请求之前将调用其中的多个函数。

function A() {
  B().subscribe();
}

function B() {
  return C().map();
}

function C() {
  return D().map();
}

function D() {
 // call http reuest and return data
}

调用者函数将执行实际订阅,而参与的所有其他函数将只是映射数据。

来到你的代码,你将不得不这样修改:

activate();

    function activate() {
        /**
         * Step 1
         * Ask the getAvengers function for the
         * avenger data and wait for the promise
         */
        return getAvengers().subscribe(
            (data) => {
            // handle your result data
            logger.info('Activated Avengers View');
        });
    }

    function getAvengers() {
          /**
           * Step 2
           * Ask the data service for the data and wait
           * for the promise
           */
          return dataservice.getAvengers()
              .map((data) => {
                  /**
                   * Step 3
                   * set the data and resolve the Observable
                   */
                  vm.avengers = data;
                  return vm.avengers;
          });
    }

答案 2 :(得分:1)

使用promises时使用.then(),使用Observables,你有足够多的operators可以组合多个observable,创建副作用,修改初始observable发出的值等等。{{1如@Supamiu所解释的那样是所有这些运算符的一个例子。

Observable不会按原样执行任何操作,它们定义数据流,它只是触发数据广播过程的订阅。

异步管道

大部分时间你都不需要map,你可以使用subscribe管道为你做角度处理。例如:

组件:

async

模板:

this.avengers$=this.dataservice.getAvengers().do(()=>console.log("Avengers fetched");

它定义数据流的事实允许您对创建非常复杂的流的事件做出反应,而没有太多的副作用或努力。

例如在点击时创建新的复仇者:

组件:

<span *ngFor="avenger of avengers$|async">{{avenger.name}}</span>

模板:

avengerClick$ = new Subject<mouseEvent>();

constructor(){
    let initialAvengers = this.dataservice.getAvengers().do(()=>console.log("Avengers fetched").switchMap(avangers);
    this.avengers$ = Observable.merge(
        initialAvengers,
        this.avengerClick.switchMap(()=>this.dataservice.createAvenger()) // let's say this.dataservice.createAvenger() returns the new list of avengers
    )
}