From de889557bf7e414837d575d46375a37072799038 Mon Sep 17 00:00:00 2001 From: Dzmitry Shylovich Date: Sun, 26 Mar 2017 13:20:09 +0300 Subject: [PATCH] fix(router): should run resolvers for the same route concurrently Fixes #14279 --- packages/router/src/utils/collection.ts | 7 ++-- packages/router/test/integration.spec.ts | 53 ++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/router/src/utils/collection.ts b/packages/router/src/utils/collection.ts index cbd99c9e34024d..65dcd8941a8909 100644 --- a/packages/router/src/utils/collection.ts +++ b/packages/router/src/utils/collection.ts @@ -10,9 +10,8 @@ import {NgModuleFactory, ɵisObservable as isObservable, ɵisPromise as isPromis import {Observable} from 'rxjs/Observable'; import {fromPromise} from 'rxjs/observable/fromPromise'; import {of } from 'rxjs/observable/of'; -import {concatAll} from 'rxjs/operator/concatAll'; import {every} from 'rxjs/operator/every'; -import * as l from 'rxjs/operator/last'; +import {last as _last} from 'rxjs/operator/last'; import {map} from 'rxjs/operator/map'; import {mergeAll} from 'rxjs/operator/mergeAll'; import {PRIMARY_OUTLET} from '../shared'; @@ -113,8 +112,8 @@ export function waitForMap( }); if (waitFor.length > 0) { - const concatted$ = concatAll.call(of (...waitFor)); - const last$ = l.last.call(concatted$); + const merged$ = mergeAll.call(of (...waitFor)); + const last$ = _last.call(merged$); return map.call(last$, () => res); } diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 50a5b97082f462..1031d8aed60114 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -844,24 +844,50 @@ describe('Integration', () => { }))); describe('data', () => { + let log: string[]; class ResolveSix implements Resolve { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): number { return 6; } } beforeEach(() => { + log = []; TestBed.configureTestingModule({ providers: [ {provide: 'resolveTwo', useValue: (a: any, b: any) => 2}, {provide: 'resolveFour', useValue: (a: any, b: any) => 4}, {provide: 'resolveSix', useClass: ResolveSix}, {provide: 'resolveError', useValue: (a: any, b: any) => Promise.reject('error')}, - {provide: 'numberOfUrlSegments', useValue: (a: any, b: any) => a.url.length} + {provide: 'numberOfUrlSegments', useValue: (a: any, b: any) => a.url.length}, + { + provide: 'resolver1', + useValue: () => { + return delayPromise(15).then(() => log.push('resolver1')); + } + }, + { + provide: 'resolver2', + useValue: () => { + return delayPromise(10).then(() => log.push('resolver2')); + } + }, + { + provide: 'resolver3', + useValue: () => { + return delayPromise(5).then(() => log.push('resolver3')); + } + }, ] }); }); - it('should provide resolved data', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + function delayPromise(delay: number): Promise { + let resolve: () => void; + const promise = new Promise(res => resolve = res); + setTimeout(() => resolve(), delay); + return promise; + } + + it('should provide resolved data', fakeAsync(inject([Router], (router: Router) => { const fixture = createRoot(router, RootCmpWithTwoOutlets); router.resetConfig([{ @@ -966,6 +992,27 @@ describe('Integration', () => { expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 3}); }))); + + it('should run resolvers for the same route concurrently', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{ + path: 'a', + resolve: { + one: 'resolver1', + two: 'resolver2', + three: 'resolver3', + }, + component: SimpleCmp + }]); + + router.navigateByUrl('/a'); + advance(fixture); + tick(15); + + expect(log).toEqual(['resolver3', 'resolver2', 'resolver1']); + }))); }); describe('router links', () => {