繁体   English   中英

在Angular服务中缓存UI的计算数据?

[英]Caching calculated data for the UI in an Angular service?

在我的应用程序中,我有这些名为Schedule TypeScript类,在UI中我希望能够将这些对象表示为自然语言描述,例如“每月的第二个星期一上午6:00”

要计算这些“计划描述”,我有一个Angular服务ScheduleDescriptionService ,我称之为getScheduleDescription() ,我将它传递给一个Schedule ,它将描述作为string返回。

不幸的是,我了解到这个getScheduleDescription()函数非常昂贵,并且它在应用程序的某些部分被调用很多。 我想要做的是通过在生成描述之后缓存描述来解决性能问题,这样就不必在每次UI想要显示它们时生成它们。

我将此函数放入Angular服务的原因是因为我需要生成这些描述的函数来访问国际化服务,据我所知,我不能将Angular服务注入普通的TypeScript类,如Schedule否则我可能已经将getScheduleDescription()放入Schedule类中,这样我就可以处理每个缓存其自身描述的Schedule

我不能使用Angular管道因为我需要能够在我的代码隐藏中获取描述所以我需要以某种方式管理缓存以获取大量的时间表描述而且我不能只在任何一个Angular组件中处理缓存因为我需要在我的应用程序中的所有位置显示这些描述。 这让我相信我必须在ScheduleDescriptionService Angular服务中缓存这些描述。

这是正确的方法吗? 如果是这样,我如何在这种情况下缓存? 如果服务持续我的应用程序的生命周期,如果我的用户查看了很多描述? 如果他们停止查看带有计划说明的页面,我应该清除缓存吗? 如何管理变更检测?

提前致谢。

我建议使用memoization ,因此,你基本上可以用昂贵的函数包装另一个函数,该函数将缓存其结果并serve the cached output as long as its parameters don't change

 function veryExpensive(arg) { for(let i = 0; i < 3000000000; i++); return `result of ${arg}`; } function memoize(worker) { let res, previousArgs; return (...args) => { console.time(`memoize(worker)("${args}")`); // shallow comparison const cacheable = previousArgs && args.every((arg, index) => arg === previousArgs[index]); if(!cacheable) { previousArgs = args; res = worker(...args); } console.timeEnd(`memoize(worker)("${args}")`); return res; }; } const memoized = memoize(veryExpensive); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('Cache Function'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); memoized('One More Cache'); 

有几种方法可以在角度应用程序中缓存状态。 您可以执行类似于服务序列化对象或对象的操作,并将它们存储在sessionStorage,localStore或cookie中。 然后在检索描述时首先在缓存中检查对象,如果它有很大的用途,如果它没有检索它并将其粘贴在缓存中。

如果你想要更精细和更强大的东西,我会看看实现ngrx 它是一个全局redux商店,为您的应用程序提供一个全局不可变存储,用于保存您的应用程序状态。 在您的情况下,想法是计算一次描述,将它们粘贴在商店中,然后让任何关心描述的组件或服务订阅商店并获得价值。

这取决于数据应该有多长。

页面刷新/跨多个选项卡可用的数据

如果您需要跨页面刷新持久化数据数据,或者在用户打开多个选项卡时可用,我会说只使用localStorage它可以存储几MB 如果您只是将计划ID存储为键,将描述存储为值,则应该有足够的数万个描述。

当列表达到特定大小或localStorage没有更多空间时,您可以管理列表并删除最旧的条目。 我不认为你需要过多担心检索时间,除非你在页面上花了好几千个时间来调用这个对象

注意:如果您计划使用angular universal,则localStorage将无法在服务器端使用。

会议期间可用的数据

您可以将值存储在JS对象或Map对象中。

使用地图

class ScheduleDescriptionService
{
    private map : Map<number, string> = new Map<number,string>();
    getScheduleDescription(schedule: Schedule)
    {
        let desc = this.map.get(schedule.id);
        if(!desc)
        {
            desc = this.internationalizationService.getDescription(schedule);
            this.map.set(schedule.id, desc);
        }
        return  desc;
    }
}

附注如果您还没有这样做,您还可以使用OnPush检测更改策略来尝试减少调用描述服务的次数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM