【问题标题】:Is n++/n-- atomic, (Running same function multiple times triggered by setinterval)是 n++/n-- 原子的,(由 setinterval 触发多次运行相同的函数)
【发布时间】:2016-07-08 01:16:17
【问题描述】:

TL;DR;

setInterval(doit,10);
function doit(if(q<10){q++;do_something().onFinished(q--)})

如果同时运行多次,q 会不一致。


我想尽可能快地加载数千张图片(缩略图)。

我尝试使用 jQuery .load,在加载一张图片时加载下一张图片,但它会慢到爬行并导致浏览器崩溃。

replace image src many times gets slow

我目前的尝试如下:

  • 我已将 400 张 ID 为 img_0 的图像预加载到 img_399
  • 我想一次加载 30 张图片

-

var q = 0    //queue length
var n = 0    //Image number

$("document").ready(function() {
    cnt=setInterval(loadimg,10); // every 10ms
})

function loadimg() {
if (q < 30) { // if less than 30 images being loaded
    m=++n;    
    q++; // increase queue length
    i = m % 400;
    $("#cnt").html(m)
    $("#queue").html(q)
    $("#img_" + i).attr('src', '//media.paradiss.dk/' + m + '').load(function() {
        q-- //decrease queue length when done.
    })
    } else {
       console.log("busy q:"+q);
    }
}

我的想法是这样的:

setInterval 每 10 毫秒触发一次 loadimg。 如果队列长度(q)小于30,loadimg增加队列长度计数器,加载图片,当图片加载完毕,队列长度递减。

但是,虽然 q 永远不会超过指定的 30,但它会突然下降到 0 以下。如果不限制,它可以达到负数。

q++ 和 q-- 不是原子的吗?

【问题讨论】:

  • 否 ++ 不是原子的。事实上,我想不出一种语言。
  • 这实际上是一个稍微无效的问题,因为 javascript 不允许多线程。使用 setInterval (或类似的)不会创建线程,而是创建异步执行。由于异步行为和计算时间的细微变化,您会得到不一致的行为,特别是因为超时只有 10 毫秒。如果您的超时时间相对较大且计算量相对较小,那么您可能会保持一致,但即便如此,也不要赌它。
  • 好的,有什么想法可以做我想做的事吗?
  • 设置一个递归循环,以便在 jquery 加载的“完成”中调用。您可以在其中放置一个计数器或使用其他方式来跟踪是否已处理所有图像。
  • 试过了。请参阅我的问题中的链接。没用。

标签: javascript jquery


【解决方案1】:

这与操作的原子性无关。事实上,JS 永远不会并行执行,没有数据竞争。所有异步事件都在队列中按顺序处理,其中每个调用都是运行到完成。

但是q突然降到0以下。如果不限制,它可以降到负数。

当您加载超过 400 张图片时。每次加载新的 src 时,您都会附加一个新的 load 回调,但您永远不会删除它们。加载 400 张图像后,img 元素将附加多个事件处理程序,当图像加载时,q 会减少多次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-12
    • 2015-12-19
    • 1970-01-01
    • 2019-11-21
    • 2021-03-19
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多