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; не Observable
s.
при рассмотрении docs, сообщения в блогах, учебники и т. д. трудно найти окончательно ответ на вопрос, является ли или нет APP_INITIALIZER
поддерживает возврат Observable
s. Понятно, что это тут поддержка Promise
s -например:
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
код; просто Promise
s.