追加按放置数量排序的项目

Posted

技术标签:

【中文标题】追加按放置数量排序的项目【英文标题】:Append items ordering by placed amount 【发布时间】:2018-04-14 05:53:08 【问题描述】:

我正在使用此功能按金额顺序附加新项目。此函数每 30-50 毫秒调用一次。

var insertBefore = false;
container.find('.roll-user-row[data-user-id="' + user_data.id + '"]').remove();

container.children().each(function () 
    var betContainer = $(this), itemAmount = $(this).attr('data-amount'), betId = $(this).attr('data-user-id');
    if (itemAmount < betData.totalAmount) 
        insertBefore = betContainer;
        return false;
    
);

if (insertBefore) 
    $(template).insertBefore(container);
 else 
    container.prepend(template);

itemAmount = $(this).attr('data-amount') 是整数,betData.totalAmount 也是整数。如果追加速度低于 ±300 毫秒 - 一切正常。在快速附加的情况下,我得到这个结果:

这甚至不是我想要的——那是随机的。如何解决?

【问题讨论】:

您是否打算始终对列表中的每个项目进行排序? 即您的目标是排序列表吗? 【参考方案1】:

我只是在这里发布方法,如果我的理解是正确的,那么我将发布代码。我首先想到的是'Virtual DOM' concept。这是你可以做的,

    仅使用高度频繁的随机函数调用来维护像对象这样的数据结构。不要依赖 DOM 更新。

    然后使用频率低得多的 setInterval 重复函数调用从该数据结构重绘(或更新)您的 DOM。

我不确定您是否有任何理由不能采用这种方法,但这将是在时间紧迫的用例中处理 DOM 的最有效方法。

【讨论】:

“30ms 频繁的函数调用”不是真的,我只是命名而已。这实际上是来自后端的套接字发射,具体取决于服务器端发生的情况。这就是为什么它是 30-50-100 毫秒 - 另一方面是随机的。 没关系,随机与否,你可以干净地更新一个数据结构。然后使用它来生成视图。【参考方案2】:

1.重构

首先,return 内的 .each 回调不起作用。它只是打破了当前的迭代,而不是所有的循环。如果你想中断 cylce,你应该使用简单的 for 循环和break 语句。然后,我建议尽可能少打电话给$(),因为这是is expensive。因此,我建议对您的函数进行以下重构:

function run() 
  container.find('.roll-user-row[data-user-id="' + user_data.id + '"]').remove();

  var children = container.children();
  for (var i = 0; i < children.length; i++) 
    var betContainer = $(children[i]); // to cache children[i] wrapping
    var itemAmount = betContainer.attr('data-amount');
    var betId = betContainer.attr('data-user-id');

    if (itemAmount < betData.totalAmount) 
      $(template).insertBefore(container);
      return; // instead of "break", less code for same logic
    
  

  container.prepend(template); // would not be executed in case of insertBefore due to "return"

2。节流

要运行 50 毫秒的重复过程,您可以使用 setInterval(run, 50) 之类的东西。如果您需要确定 run 已完成并且这是 300 毫秒延迟,那么您可以只使用 setInterval(run, 300)。但是,如果进程以您无法更改的方式初始化,并且 50ms 是固定间隔,那么您可以通过 lodash throttle 或 jquery throttle plugin 保护 run 调用:

var throttledRun = _.throttle(run, 300); // var throttledRun = $.throttle(300, run);
setInterval(throttledRun, 50);

setInterval 只是一个例子,您需要在中继器初始化逻辑中将初始 run 替换为节流版本 (throttledRun)。这意味着 run 将在自上一次执行 run 之后的 300 毫秒间隔后才会执行。

【讨论】:

它看起来是正确的答案,但我无法将其标记为正确,因为它会创建等待附加队列并带有油门。我需要的是实时更新,因为有 15 秒的时间来追加所有元素。在那 15 秒之后,我只需要取消油门而不添加新元素,对吗?如果我错了,请纠正我。 @Sandra Throttling 只是跳过不需要的呼叫,它不会创建队列。因此,我们在这里进行了实时节流。您可以通过throttledRun.cancel() 取消尾随节流调用。只需在您需要的地方调用它即可。您也可以覆盖所有过程以使其无效:run = function() return null; 或添加预防性条件return 或......任何用例都有很多方法,只需要澄清用例即可。 所以我尝试了这种方法,但仍然面临同样的问题。回调在随机时间范围内,介于 50 到 ±300 毫秒之间。感谢您的帮助! @Sandra 我相信,您的问题可以很容易地解决,并且可以帮助解决的问题是可重现的演示。 jsfiddle、plunker 或其他任何适合复制的选项。问题出在您在问题中提供的代码之外。

以上是关于追加按放置数量排序的项目的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB,按两个数组之间匹配元素的数量对结果进行排序

用户按下排序按钮后如何在列表视图中显示排序列表?

使 jQuery 可放置接受来自使用 connectWith 的可排序的项目

按项目名称对交易进行分组

响应式布局的一种实现方案,宽度不一样放置元素数量不一样

如何将可拖动的元素放入可排序的元素中,放置的项目不是原始元素而是自定义助手