我有基于AngularV4的应用程序。这个场景很简单-我需要在应用程序启动之前从服务器加载一些设置。为此,我使用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()
有人能解释为什么会这样吗?
最佳答案
原因很简单:load_one
起作用,load_two
不起作用:angular只会等待Promise
s;而不会等待Observable
s。
当查看docs、博客文章、教程等时,很难确定APP_INITIALIZER
是否支持返回Observable
s。很明显,它确实支持Promise
s-e.g.:
如果函数返回一个promise直到promise解析,angular将延迟初始化。
为了确定,实际上可以看到角度code在做什么:
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。