Angular2 Observable - 如何等待循环中的所有函数调用在继续之前结束?

时间:2016-02-23 01:05:08

标签: javascript angular observable angular-promise

我试图通过迁移当前用Angular1编写的应用程序来提高我对Angular2的了解

特别令我难过的一个特点。我试图复制一个功能,其中一个调用函数等待继续,直到它调用的函数完成了一个promises循环。在有角度的一个中,我调用的函数看起来基本上是这样的:

this.processStuff = function( inputarray, parentnodeid ) {
    var promises = [];
    var _self = this;
    angular.forEach( inputarray , function( nodeid ) {

        switch ( parentnodeid )
        {
            case ‘AAA’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
            case ‘BBB’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
            case ‘CCC’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
            default    : var component = null;
        }
        promises.push( component );
    });
    return $q.all(promises);
}; 

它包含一个forEach循环,它调用另一个函数(doMoreStuff),该函数也返回一个promise,它将所有返回的promises存储在一个数组中。

使用Angular1,当我在另一个函数中调用processStuff时,我可以指望系统等到processStuff完成后再进入then块中的代码。 IE:

service.processStuff( arraying, parentidarg )
       .then(function( data ) {
              ... 

processStuff的调用者等待所有doMoreStuff次调用完成,直到processStuff的调用者进入其then块。

我不确定如何使用Angular2和Observables实现此目的。我可以从这些帖子中看到,为了模仿承诺,Observables基本上只使用subscribe而不是那时:

Angular 1.x $q to Angular 2.0 beta

但是如何在我的系统继续进行之前等待forEach循环中的所有调用完成?

2 个答案:

答案 0 :(得分:64)

我一直用forkJoin

这样做
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

Observable.forkJoin(
  this.http.get('./friends.json').map((res: Response) => res.json()),
  this.http.get('./customer.json').map((res: Response) => res.json())
)
.subscribe(res => this.combined = {friends: res[0].friends, customer: res[1]});

此处提供更多信息:http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http

答案 1 :(得分:1)

在RxJS v6和更高版本中,您可以使用 zip 更雄辩地做到这一点。

    import { zip } from 'rxjs';

    const promise1 = yourSvc.get(yourFavoriteAPI.endpoint1);
    const promise2 = yourSvc.get(yourFavoriteAPI.endpoint2);

    const promises = zip(promise1, promise2);

    promises.subscribe(([data1, data2]) => {
      console.log(data1);
      console.log(data2);
    });

虽然结果相同,但我发现zipforkJoin更可取,因为zip更通用,并且可以处理来自可观察对象的新值。

rxjs documentation中的详细信息:

zip 运算符将订阅所有内部可观测对象,等待 每个都发出一个值。一旦发生这种情况,所有带有 相应的索引将被发出。这将持续到至少 一个内部可观察的对象完成。