在Breeze实体上调用ko.toJS会导致长时间运行的脚本缓慢 [英] Calling ko.toJS on Breeze entity causes slow long running script

查看:99
本文介绍了在Breeze实体上调用ko.toJS会导致长时间运行的脚本缓慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在具有导航属性或属于大对象图IE7-8的任何Breeze实体上调用ko.toJS(entity)时,它会抱怨脚本运行时间长,甚至chrome也会停滞1秒钟以上.

When calling ko.toJS(entity) on any Breeze entity that has navigation properties or is part of a large object graph IE7-8 complain of long running script errors and even chrome can get bogged down for over 1 second.

推荐答案

我以前曾对此感到困扰,并看到过各种论坛或Github问题,这已成为开发人员的问题.我想分享一些知识,希望对其他人有帮助.

I have had this plague me before and seen various forums or Github issues where this became an issue for devs. I wanted to share some knowledge in hopes that it helps others.

问题

Breeze.js为您的客户端库或框架提供对象图.在实体上调用JSON.stringify()会导致可怕的堆栈溢出,因为某些属性相互引用.示例-

Breeze.js provides your client-side libraries or frameworks with an object graph. Calling JSON.stringify() on the entity will cause the dreaded stack overflow because some of the properties reference each other. Example -

Person -> Company -> Persons

由于某人具有公司的导航属性,而该公司又具有某人的导航属性,因此他们可以继续彼此找到对方.

Since a person has a navigation property of company that also has a navigation property of persons they continue to find each other.

ko.toJS()通过检测重复项并在该点停止序列化来解决此问题.

ko.toJS() gets around this by detecting duplicates and stopping the serialization at that point.

为什么慢?

序列化需要更长的时间,具体取决于对象图中实体的数量.不相信我吗?加载您的应用程序并调用ko.toJS(),然后在同一对象图中加载更多的实体.这将需要更长的时间,有保证.问题在于,即使您在一个人身上调用ko.toJS(),淘汰赛也不会发现重复项,除非它已对原始人公司中的每个人进行了序列化.这不是淘汰赛或微风问题,而是所有事物之间相互联系的程度所致.

The serialization takes longer depending on the number of entities in the object graph. Don't believe me? Load your app and call ko.toJS() then go load up a bunch more entities in the same object graph. It will take longer, guaranteed. The problem is that even if you call ko.toJS() on a single person Knockout isn't finding duplicates until it has serialized every person in the original persons company. This isn't a problem of Knockout nor Breeze - it is caused by how well interconnected everything is.

该如何解决?

如果可以的话,使用投影查询是最好的解决方案.问题通常是我们需要更深层次的实体嵌套层,而不仅仅是当前实体.如果您的实体具有包含许多相关实体的导航属性,则没有简单的方法来执行投影查询,因此我们需要采用以下两种方法中的一种来使它更进一步-

Using a projection query is the best solution, if you can. The problem is usually we need deeper nested levels of entities, not just the current entity. If your entity has a navigation property that has many related entities there is no easy way to perform a projection query, so we need to take it a step further in one of two manners -

  1. 编写自定义序列化器

  1. Write a custom serializer

我的看法-将实体管理器上的方法公开为展开",该方法接受以下参数-

My opinion - expose a method on the entity manager to 'unwrap' that accepts the following parameters -

entityManager.unwrap(entity || [entities], [addtlTypesToUnwrap])

其中的addtlTypesToUnwrap是字符串数组或逗号分隔的字符串,用于定义要解包的相关实体类型.

Where addtlTypesToUnwrap is either an array of strings or comma separated strings that define which related entity types to unwrap.

示例用法-

var thisEntity = manager.fetchEntityByKey('Person', 1, true);
var relatedProps = ['Company', 'Address']
entityManager.unwrap(thisEntity, relatedProps);

哪些人将解散Person,他们的地址,他们的公司以及公司的地址(如果存在)

Which would unwrap Person, their address, their company, and the companies address (if it existed)

这篇关于在Breeze实体上调用ko.toJS会导致长时间运行的脚本缓慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆