Angular-инициализатор приложения-Promise vs Observable

у меня есть приложение, основанное на Angular v4. Сценарий прост - мне нужно загрузить некоторые настройки с сервера до запуска приложения. Для этого я использую APP_INITIALIZER:

{
  provide: APP_INITIALIZER,
  useFactory: init,
  deps: [SettingsService],
  multi: true
}

export function init(config: SettingsService) {
   return () => config.load_one();
}

//import declarations    
@Injectable()
export class SettingsService {
  constructor(private http: HttpClient) { }

  load_one(): Promise<boolean> {
    return new Promise<boolean>((resolve) => {
        this.http.get('url').subscribe(value => {
            console.log('loadSettings FINISH');
            resolve(true);
        });
    });
  }

  load_two(): Observable<any> {
    const promise = this.http.get('url');

    promise.subscribe(value => {
        console.log('loadSettings FINISH');
    });

    return promise;
  }
}

где-то в приложении, у меня есть функция, называемая manageSettings() (его код не на данный момент), который требует, чтобы данные из SettingsService сервис инициализируется.

и вот что-когда я использую функцию load_two(), приложение не ждет, пока он завершает:

app-root constructor
manageSettings()
loadSettings FINISH

и когда я использую функцию load_one() он отлично работает:

loadSettings FINISH
app-root constructor
manageSettings()

может кто-нибудь объяснить, почему это происходит ?

1 ответов


причина load_one и load_two не просто: угловой будет только ждать Promise s; не Observables.

при рассмотрении docs, сообщения в блогах, учебники и т. д. трудно найти окончательно ответ на вопрос, является ли или нет APP_INITIALIZER поддерживает возврат Observables. Понятно, что это тут поддержка Promises -например:

Angular задержит инициализацию, если функция возвращает обещание до разрешения обещание.

чтобы быть уверенным, вы действительно можете увидеть, что угловой код делаем:

if (isPromise(initResult)) {
    asyncInitPromises.push(initResult);
}

здесь isPromise определяется следующим образом:

export function isPromise(obj: any): obj is Promise<any> {
    // allow any Promise/A+ compliant thenable.
    // It's up to the caller to ensure that obj.then conforms to the spec
    return !!obj && typeof obj.then === 'function';
}

ссылки Observable на APP_INITIALIZER код; просто Promises.