【问题标题】:Spinlock in JavascriptJavascript 中的自旋锁
【发布时间】:2011-11-06 22:40:45
【问题描述】:

如何在 javascript 中进行自旋锁?

我正在尝试加载一堆图像,我只能在加载完所有内容后继续前进,所以我有一个类似的自旋锁

for(...)
   image[i].onload = function() { ++imagesloaded; }

while(imagesloaded != totalimages)
{
}

它使我的浏览器崩溃。有更好的方法吗?还是我缺少的 yield / sleep 功能?

【问题讨论】:

    标签: javascript loops loader spinlock


    【解决方案1】:

    简短回答:不要自旋。


    更长的答案:这是如何做到的:

    var imagesLoaded = 0;
    var totalImages = 42;
    
    function handleImageLoad()
    {
        imagesLoaded++;
        if (imagesLoaded === totalImages)
        {
            doSomething();
        }
    }
    
    for (var i=0; i<totalImages; i++)
    {
        image[i].onload = handleImageLoad;
    }
    

    一般来说,当您想在 JavaScript 中休眠/等待/旋转时,请考虑通过回调(和setTimeout/setInterval)来解决问题。

    【讨论】:

    • 请记住,在图像上设置.src 之前,您必须设置onload() 处理程序。否则,如果图像从缓存中加载(因此加载速度非常快),您可能会错过某些浏览器中的 onload() 事件。
    【解决方案2】:

    上面的答案没有用,因为浏览器中的限制/错误可能需要自旋锁。例如,当您想在 javascript 中生成文件时,safari(希望不是将来的版本)需要使用方法 window.open。这样做的结果是您无法使用任何回调生成文件(因为弹出窗口阻止程序),这实际上强制使用首先调用文件生成函数(使用回调)的对话框窗口,然后是下载文件的按钮.由于自旋锁不起作用,代码变为以下内容:

    function process(callback) {
      processCallbackData = null; // global var that must be a unique name
      callback(function(data) {
         processCallbackData = data;
      });
    }
    
    function fowardButton() {
      if(processCallbackData!=null) {
         goForwardUsingCallbackIncompatibleCode();
      } else {
         displayStillLoadingWarning();
      }
    }
    

    【讨论】:

      【解决方案3】:

      不要使用循环来检查。检查事件处理函数。 (所以你只在图像加载时进行检查,而不是尽可能快地连续检查)

      【讨论】:

      猜你喜欢
      • 2013-09-27
      • 2016-08-12
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 2014-11-15
      相关资源
      最近更新 更多