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.
