繁体   English   中英

在创建数千个子记录后,Ember.js / Ember Data需要几分钟才能更新hasMany的父级

[英]Ember.js/Ember Data takes several minutes to update hasMany of parent after creating thousands of child records

我是Ember.js的新手,在尝试创建数千条记录(确切地说是5300)并更新hasMany关系时会遇到性能问题。 在创建新记录之前,我正在向API请求检索记录。 在承诺返回之后,我然后对每个记录下来的记录(5300)执行forEach以对新记录集进行计算。 创建记录本身大约需要2秒钟。 更新hasMany仅对前40个左右的记录快速启动,然后减慢到每秒约一个更新。

我还应该注意到,这是在一个组件内完成的。 我知道这通常是anit-pattern,但在这种情况下,没有理由更改URL或转换。 这是一个屏幕,用户可以从一个项目池(由路径提供)中进行选择,应用定价规则,然后根据这些项目创建一个事件(在路径中创建)。 这是一个沙箱,用于确定哪些项目将成为活动的一部分。 一旦用户决定了他们的活动项目,我就会向该路线发送一个动作来执行实际的保存并持续到我的后端。 在反模式方面之外,我无法看到这将如何影响hasMany更新的性能。

我正在使用RESTAdapter和RESTSerializer来获取它的价值,但这不应该对我有任何影响,因为我只是处理Ember数据存储。

灰烬版:

Ember             : 2.5.1
Ember Data        : 2.5.3
jQuery            : 2.2.3
Ember Simple Auth : 1.1.0

有问题的两个模型如下......

儿童模特(事件项目):

export default DS.Model.extend({
  event: DS.belongsTo('event'),
  itemNumber: DS.attr('string'),
  styleNumber: DS.attr('string'),
  tier: DS.attr('string'),
  eventPrice: DS.attr('number')
});

父模型(事件):

export default DS.Model.extend({
  eventTypeId: DS.attr('string'),
  eventName: DS.attr('string'),
  eventDesc: DS.attr('string'),
  startDate: DS.attr('moment-date'),
  endDate: DS.attr('moment-date'),
  priority: DS.attr('number'),
  statusCode: DS.attr('string'),
  value: DS.attr('number'),
  eventItems: DS.hasMany('event-item', {async:true})
});

活动创建记录:

model() {
    return this.store.createRecord('event', {});
},

负责创建记录和更新hasMany的组件中的代码块:

this.get('store').query('pricing', {brandCd: '00'}).then(tiers => {
    tiers.forEach(tier => {
        this.get('event').get('eventItems').createRecord({
            styleNumber: tier.get('styleNumber'),
            itemNumber: tier.get('itemNumber'),
            brandCd: '00',
            tier: tier.get('tier'),
            eventPrice: this._calculateEventPrice(tier.get('origPrice'), this.get('event').get('eventTypeId'), this.get('event').get('value')),
        });
    });

    this.get('event').set('needsUpdated', 'Y');
});

到目前为止,我已尝试过以下内容......

  • 添加与我的hasMany和belongsTo的反向关系
  • 将所有创建记录添加到Ember.A() ,然后尝试将新记录推送到hasMany,如下所示: this.get('event').get('eventItems').pushObjects(newEventItems); 还尝试使用this.get('event').get('eventItems').addObjects(newEventItems);
  • 在正在创建的记录上设置belongsTo,而不是更新父(事件)的hasMany。
  • 我也继续前进并将这个逻辑移到我的路线中,以确保我在组件中执行此操作时没有得到奇怪的行为。 它执行相同的操作。

我认为(如果我错了请纠正我),严格在客户端创建记录和更新关系应该能够处理数千条记录而不会出现太多问题。 我希望我只是做一些不正确的事情,或者以一种效率低下的方式对那些经验丰富的人来说是显而易见的。 任何帮助,包括替代品,非常感谢!

我发现使用大量'hasMany'关系也很慢。

我的建议:使用自定义端点在服务器上构建关系,并通过websockets将更改传回客户端。 尝试在Ember中单独保存5300条记录将产生5300个网络请求,而这可以在1个出站请求中完成,可能还有一个websockets消息,尽管建议将响应批量处理为较小的集合。

在更改提交之前,无需在Ember中建立关系。 返回的websockets消息应该包含关系的外键Ember Data需要构建关系。

这意味着,在没有父级的情况下,您将创建eventItems (或任何模型被调用)。

最后,您可以考虑按需创建子记录,而不是尝试立即为用户创建每个子项。 当用户决定从项目池中选择项目时,只需执行createRecord (希望我能正确理解你的用例。)如果采用这种方法,你甚至可能根本不需要使用我所描述的自定义端点。

最后一点建议:你关于'反模式'的说明是正确的:永远不要在组件中进行CRUD操作或任何真正的异步操作, 特别是对于5300项 在异步操作完成之前,可以轻松地拆除组件,使应用程序处于奇怪的状态,并且很可能导致错误。 像你说的那样将你做的任何事情移动到路线中,并坚持使用那种模式。 组件应该只是“哑”模板,显示东西和发送动作。

暂无
暂无

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

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