From bb94e6b7634e70a873881f406a955591ae401b0b Mon Sep 17 00:00:00 2001 From: vthinkxie Date: Thu, 17 Oct 2019 17:48:35 +0800 Subject: [PATCH] feat(core): support APP_INITIALIZER work with observable add support to observable with APP_INITIALIZER close #15088 --- packages/core/src/application_init.ts | 4 +- packages/core/test/application_init_spec.ts | 50 ++++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/core/src/application_init.ts b/packages/core/src/application_init.ts index d464573b44b0b2..d5531a1e0c47ff 100644 --- a/packages/core/src/application_init.ts +++ b/packages/core/src/application_init.ts @@ -7,7 +7,7 @@ */ import {Inject, Injectable, InjectionToken, Optional} from './di'; -import {isPromise} from './util/lang'; +import {isObservable, isPromise} from './util/lang'; import {noop} from './util/noop'; @@ -68,6 +68,8 @@ export class ApplicationInitStatus { const initResult = this.appInits[i](); if (isPromise(initResult)) { asyncInitPromises.push(initResult); + } else if (isObservable(initResult)) { + asyncInitPromises.push(initResult.toPromise()); } } } diff --git a/packages/core/test/application_init_spec.ts b/packages/core/test/application_init_spec.ts index ee078a606ea0f4..dbde730e20986f 100644 --- a/packages/core/test/application_init_spec.ts +++ b/packages/core/test/application_init_spec.ts @@ -7,6 +7,7 @@ */ import {Injector} from '@angular/core'; import {APP_INITIALIZER, ApplicationInitStatus} from '@angular/core/src/application_init'; +import {Observable, Subscriber} from 'rxjs'; import {inject, TestBed, waitForAsync} from '../testing'; @@ -28,7 +29,7 @@ import {inject, TestBed, waitForAsync} from '../testing'; }))); }); - describe('with async initializers', () => { + describe('with async promise initializers', () => { let resolve: (result: any) => void; let promise: Promise; let completerResolver = false; @@ -57,7 +58,7 @@ import {inject, TestBed, waitForAsync} from '../testing'; }); }); - it('should update the status once all async initializers are done', + it('should update the status once all async promise initializers are done', waitForAsync(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => { (status as any).runInitializers(); @@ -66,6 +67,51 @@ import {inject, TestBed, waitForAsync} from '../testing'; resolve(null); }); + expect(status.done).toBe(false); + status.donePromise.then(() => { + expect(status.done).toBe(true); + expect(completerResolver).toBe(true); + }); + }))); + }); + describe('with async observable initializers', () => { + let resolve: Subscriber; + let observable: Observable; + let completerResolver = false; + beforeEach(() => { + let initializerFactory = (injector: Injector) => { + return () => { + const initStatus = injector.get(ApplicationInitStatus); + initStatus.donePromise.then(() => { + expect(completerResolver).toBe(true); + }); + }; + }; + observable = new Observable((res) => { + resolve = res; + }); + TestBed.configureTestingModule({ + providers: [ + {provide: APP_INITIALIZER, multi: true, useValue: () => observable}, + { + provide: APP_INITIALIZER, + multi: true, + useFactory: initializerFactory, + deps: [Injector] + }, + ] + }); + }); + + it('should update the status once all async observable initializers are done', + waitForAsync(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => { + (status as any).runInitializers(); + + setTimeout(() => { + completerResolver = true; + resolve.complete(); + }); + expect(status.done).toBe(false); status.donePromise.then(() => { expect(status.done).toBe(true);