我有一个服务,它有选择地加载一些数据并同时将它缓存在内存中。如果稍后请求相同的数据,则服务返回缓存的副本。从服务检索数据的方法返回backtrace
:
Promise
我有另一个对象,其中包含要显示的export class MyService {
users = [];
getSingleUser(id: string): Promise<User> {
if (this.users[id]) return Promise.resolve(this.users[id]);
return new Promise(resolve => {
this.fetchUserFromNetwork(id)
.then(user => {
this.users[id] = user;
resolve(user);
})
})
}
getUsersList(idList: string[]): Promise<User[]> {
return Promise.all(idList.map(id => this.getSingleUser(id)));
}
}
列表。
userId
现在我想在模板中呈现此信息。在组件类中,我引用了export class MyReport {
userIds = [];
addUserId(id: string) { this.userIds.push(id) }
}
(MyReport
)的单例实例以及this.report
(MyService
)的单例实例。 OTHER 页面中的UI控件允许EndUser在this.service
实例中添加/删除userIds
列表。
为了呈现列表,我使用:
this.report
然而,这最终会无限次地调用<div *ngFor="let user of (this.service.getUsersList(this.report.userIds) | async)">
User: {{ user | json }}
</div>
。这么多,浏览器线程有效地挂起了。
如何解决此问题?我认为问题是这样的:Angular2调用MyService.getUsersList(...)
,通过this.service.getUsersList(...)
管道传递它以获取列表,然后呈现它。然后再次调用相同的方法以查看ChangeDetection循环是否完成。但是,即使数据未更改,数组引用也已更改。所以它一遍又一遍地做着。
我的目标如下:
呈现承诺返回的数据:async
如果在应用程序中的任何位置修改了this.service.getUsersList(this.report.userIds)
,则自动更新呈现的列表。
不会以无限循环结束。 =)
答案 0 :(得分:2)
每次执行函数时,Promise.all都会创建一个promise。 您可以简单地创建一个变量来保存值,而不是每次都创建它
private _usersPromise: Promise<User[]>;
getUsersList(idList: string[]): Promise<User[]> {
if(this._usersPromise) return this._usersPromise;
return this._usersPromise = Promise.all(idList.map(id => this.getSingleUser(id)));
}