追加按放置数量排序的项目
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 或其他任何适合复制的选项。问题出在您在问题中提供的代码之外。以上是关于追加按放置数量排序的项目的主要内容,如果未能解决你的问题,请参考以下文章