问题
Given the following route:
path: '',
component: MyComponent,
resolve: {
foo: FooResolver,
bar: BarResolver
}
Is there any way of telling angular to execute the first resolver FooResolver, and only execute the second resolver BarResolver once the first one has finished?
回答1:
Resolvers are resolved in parallel. If Foo and Bar are supposed to be resolved in series they should be a single FooBar resolver. If they are supposed to be used by themselves in other routes, FooBar can wrap Foo and Bar resolvers:
class FooBarResolver implements Resolve<{ foo: any, bar: any }> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) {}
async resolve(route): Promise<{ foo: any, bar: any }> {
const foo = await this.fooResolver.resolve(route);
const bar = await this.barResolver.resolve(route);
return { foo, bar };
}
}
FooBar should be aware of the fact if it is a promise or an observable that is returned from Foo and Bar in order to resolve them properly. Otherwise additional safety device should be added, like await Observable.from(this.fooResolver.resolve(route)).toPromise().
FooBar and Foo or Bar shouldn't appear within same route because this will result in duplicate resolutions.
回答2:
I found a slightly more elegant solution that can be used if you don't care about the results from all of the resolvers:
class FooBarResolver implements Resolve<Observable<any>> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) { }
resolve(): Observable<any>
{
return this.fooResolver.resolve().pipe(
concat(this.barResolver.resolve()),
concat(this.barResolver.resolve())
);
}
}
I use this to trigger the data loading in my services. And because they write the data / isLoading / error into an Akita storage, I don't care about the results of the resolvers.
回答3:
I tackled this scenario using combineLatest in a single resolver. You can do this:
@Injectable({providedIn: 'root'})
export class FooBarResolver implements Resolve<any> {
constructor(
private readonly fooResolver: FooResolver,
private readonly barResolver: BarResolver
) {}
resolve() {
return combineLatest(
this.fooResolver.resolve(),
this.barResolver.resolve()
).pipe(map(([users, posts]) => ({users, posts})))
}
}
来源:https://stackoverflow.com/questions/46792626/executing-resolvers-one-after-the-other-in-angular-2