我有一项服务,可以有选择地加载一些数据并将其同时缓存在内存中。如果以后再请求相同的数据,则该服务将返回缓存的副本。从服务中检索数据的方法返回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
要显示的s的列表。
export class MyReport {
userIds = [];
addUserId(id: string) { this.userIds.push(id) }
}
现在,我想在模板中呈现此信息。在组件类中,我引用了MyReport
(this.report
)的单例实例以及MyService
(this.service
)的单例实例。其他页面中的UI控件允许最终用户添加/删除实例userIds
内部的列表this.report
。
要渲染列表,我使用:
<div *ngFor="let user of (this.service.getUsersList(this.report.userIds) | async)">
User: {{ user | json }}
</div>
但是,这最终导致调用MyService.getUsersList(...)
了无数次。如此之多,以至于浏览器线程有效地挂起。
我该如何解决这个问题?我认为问题是这样的:Angular2调用this.service.getUsersList(...)
,通过async
管道将其传递以获取列表,然后进行渲染。然后,它再次调用相同的方法以查看ChangeDetection循环是否完成。但是,即使数据未更改,数组引用也已更改。因此,它会一遍又一遍地做下去。
我的目标如下:
渲染诺言返回的数据: this.service.getUsersList(this.report.userIds)
如果this.report.userIds
在应用程序中的任何位置进行了修改,则自动更新呈现的列表。
不会陷入无限循环。=)
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)));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句