Angular2 Observable - 在继续之前等待多个函数调用
Angular2 Observable - Await multiple function calls before proceeding
我正在尝试通过迁移目前用 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
),该函数也是 returns 一个承诺,并将所有返回的承诺存储在一个数组中。
使用 AngularJS,当我在另一个函数中调用 processStuff
时,我可以指望系统等到 processStuff
完成后再进入 then 块中的代码:
service.processStuff( arraying, parentidarg )
.then(function( data ) {
...
processStuff
的调用者等待所有 doMoreStuff
调用完成,直到 processStuff
的调用者进入其 then
块。
我不确定如何使用 Angular2 和 Observables 实现这一点。从这些帖子中我可以看出,为了模仿承诺,Observables 基本上只使用 subscribe()
而不是 then()
:
Angular 1.x $q to Angular 2.0 beta
但是我如何等待 forEach
循环中的所有调用完成才能继续我的应用程序?
我一直在用 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
在 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);
});
虽然结果相同,但我发现 zip
比 forkJoin
更可取,因为 zip
更通用并且可以处理来自 observables 的新值。
来自 rxjs documentation 的详细信息:
The zip operator will subscribe to all inner observables, waiting for
each to emit a value. Once this occurs, all values with the
corresponding index will be emitted. This will continue until at least
one inner observable completes.
我正在尝试通过迁移目前用 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
),该函数也是 returns 一个承诺,并将所有返回的承诺存储在一个数组中。
使用 AngularJS,当我在另一个函数中调用 processStuff
时,我可以指望系统等到 processStuff
完成后再进入 then 块中的代码:
service.processStuff( arraying, parentidarg )
.then(function( data ) {
...
processStuff
的调用者等待所有 doMoreStuff
调用完成,直到 processStuff
的调用者进入其 then
块。
我不确定如何使用 Angular2 和 Observables 实现这一点。从这些帖子中我可以看出,为了模仿承诺,Observables 基本上只使用 subscribe()
而不是 then()
:
Angular 1.x $q to Angular 2.0 beta
但是我如何等待 forEach
循环中的所有调用完成才能继续我的应用程序?
我一直在用 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
在 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);
});
虽然结果相同,但我发现 zip
比 forkJoin
更可取,因为 zip
更通用并且可以处理来自 observables 的新值。
来自 rxjs documentation 的详细信息:
The zip operator will subscribe to all inner observables, waiting for each to emit a value. Once this occurs, all values with the corresponding index will be emitted. This will continue until at least one inner observable completes.