Angular2 Observable - 在继续之前等待多个函数调用

Posted

技术标签:

【中文标题】Angular2 Observable - 在继续之前等待多个函数调用【英文标题】:Angular2 Observable - Await multiple function calls before proceeding 【发布时间】:2016-06-04 15:55:56 【问题描述】:

我正在尝试通过迁移当前用 Angular1/AngularJS 编写的应用程序来提高我对 Angular2 的了解。

特别是一个功能让我很难过。我正在尝试复制一个功能,其中调用函数等待继续,直到它调用的函数完成了一个承诺循环。在 AngularJS 中,我调用的函数基本上是这样的:

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,并将所有返回的 Promise 存储在一个数组中。

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

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

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

我不确定如何使用 Angular2 和 Observables 来实现这一点。我从这些帖子中可以看出,为了模仿 promise,Observables 基本上只是使用 subscribe() 而不是 then()

Angular 1.x $q to Angular 2.0 beta

但是我如何等待forEach 循环中的所有调用完成,然后我的应用程序才能继续执行?

【问题讨论】:

【参考方案1】:

我一直在用 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

【讨论】:

forkJoin 的参数可以是数组吗?您能否展示一个示例,您正在使用 for 循环进行迭代以填充此“数组”。我不确定循环是在新的 Observable 块内部还是外部以及如何使用observer.next();和observer.complete(); 具体导入说明请参见此处:***.com/questions/34581471/… 可以,可以是数组:github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/… 另外:导入'rxjs/add/observable/forkJoin' Rx 团队为什么选择名称forkJoin?为什么不将其称为 withwhen 之类的描述性内容? forkJoin 不清楚它的作用【参考方案2】:

在 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 操作符将订阅所有内部可观察对象,等待 每个发出一个值。一旦发生这种情况,所有值与 将发出相应的索引。这将持续到至少 一个内部 observable 完成。

【讨论】:

以上是关于Angular2 Observable - 在继续之前等待多个函数调用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular2 中停止 observable.timer

Angular2 RxJS 得到“Observable_1.Observable.fromEvent 不是函数”错误

Rxjs 过滤器运算符不适用于 Angular2 Observable

在Angular2中将自定义指令绑定到Observable

如何在Angular2中使用Observable通过id查找数组的元素

Angular2 Observable 和 Promise