简体   繁体   English

JavaScript img onLoad和闭包-为什么此代码触发无限循环?

[英]JavaScript img onLoad and closures - why does this code trigger an infinite loop?

I have some Google Maps JS that plots a number of markers on a map. 我有一些Google Maps JS,可在地图上绘制许多标记。 However, when loading the markers I noticed that the images were not loading in time and so the markers were not being placed. 但是,在加载标记时,我注意到图像没有及时加载,因此没有放置标记。 To get around this I modified my function that returned a map marker as follows: 为了解决这个问题,我修改了返回地图标记的函数,如下所示:

function newGoogleMapPin(type){
    var imgpath = "img/gmapicons/"+type+".png";
    var img = new Image();
        img.src = imgpath;
    var imgloaded = false;

    while(imgloaded == false) {
        img.onload = function() {
            imgloaded = true;
        }
    }

    return new google.maps.MarkerImage(imgpath, new google.maps.Size(img.width, img.height));
}

Problem being is imgloaded is never set to true , Am I misunderstanding closures? 问题是imgloaded从未设置为true ,我是否误解了闭包? (I guess so!) (大概吧!)

You have to keep in mind that JavaScript is fundamentally single-threaded, and this single thread is actually shared between JavaScript execution and browser rendering. 您必须记住,JavaScript基本上是单线程的,并且实际上该单线程在JavaScript执行和浏览器渲染之间共享。 Therefore your while loop will block the thread, and will loop forever. 因此,您的while循环将阻塞线程,并将永远循环。

while(imgloaded == false) {
    // onload will never get called:
    img.onload = function() {
        imgloaded = true;
    }
}

All you are doing in your while loop is setting the onload handler of the image to a function. 在while循环中,您要做的就是将图像的onload处理程序设置为一个函数。 The function never actually gets called. 该函数从未真正被调用。

You should just set the onload handler once, and have the handler do whatever's required with the image (add the pin). 您应该只设置一次onload处理程序,然后让该处理程序对图像进行任何所需的操作(添加图钉)。

Something like this: 像这样:

function newGoogleMapPin(type){
    var imgpath = "img/gmapicons/"+type+".png";
    var img = new Image();
    img.src = imgpath;
    img.onload = function() {
       new google.maps.MarkerImage(imgpath, new google.maps.Size(img.width, img.height));
    }
}

imgloaded in your code is a local variable (in the scope of newGoogleMapPin function). 在您的代码中imgloaded是一个局部变量(在newGoogleMapPin函数的范围内)。 Thus, the imgloaded variable set in the onload callback is another variable. 因此,在onload回调中设置的imgloaded变量是另一个变量。 The first variable is always false in this case, which is causing an infinite loop. 在这种情况下,第一个变量始终为false,这将导致无限循环。

To resolve the issue declare it as a global variable outside the function block. 要解决该问题,请将其声明为功能块外部的全局变量。

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

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