等待Lazy Loaded对象没有锁定?

时间:2009-05-24 03:30:46

标签: javascript lazy-loading

我已经有了延迟加载脚本请求的代码。我现在的问题是等待执行某些代码,直到该对象可用。我不能使用setTimeout(),因为它不会阻止执行。

那么在不锁定浏览器的情况下,“等待”加载的好方法是什么?

同样,不能使用原始的setTimeout()。

3 个答案:

答案 0 :(得分:3)

假设您控制脚本的内容,您可以在延迟加载的脚本的底部放置一些代码,以向主页指示脚本已加载。例如,在您的页面中,您可以执行以下操作:

var loadingScripts = 0;
var loadScript = function() {
    // Do what you need to do to load the script...

    loadingScripts++;
}

var loadedScript = function() {
    loadingScripts--;
    if (loadingScripts == 0) {
        // Kick off execution of code that requires the lazy loaded scripts.
    }
}

然后在您的脚本中,您将此代码添加到底部:

loadedScript();

您可以使用数组而不是整数来添加此示例(以跟踪已加载的特定脚本)。您还可以使用对象来将特定函数调用与特定脚本的完成相关联。我保持我的例子简单,但问你是否要我展示如何扩展代码。


以下是如何使用回调在加载脚本时继续执行特定代码(同样,假设您自己控制脚​​本)。

var scriptCallbacks = {}
var loadScript = function(scriptname, callback) {
    // Do what you need to load scriptname

    scriptCallbacks[scriptname] = callback;
}

var loadedScript = function(scriptname) {
    (scriptCallbacks[scriptname])();
}

然后当你想加载一个脚本时,你会做这样的事情......

var callback = function() {
    // Write exactly what you want executed once your script is loaded
}

loadScript("MyScript.js", callback);

再次,在您的延迟加载脚本中,只需将此代码添加到底部即可通知您的回调:

loadedScript("MyScript.js");

答案 1 :(得分:2)

我实际上的做法与Daniel提到的不同。所有元素在加载时都会触发加载事件,并在评估内容后加载Javascript文件。因此,您可以将事件处理程序设置为在可用后继续执行:

var loadScript = function(fileName, callback) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = fileName;

    script.onload = callback;
    script.onreadystatechange = function() {
        if(this.readyState == 'complete') {
            callback();
        }
    };
    head.appendChild(script);
};

一个示例用法:

var bar = function() {
    Foo.baz();
};
if(!window.Foo) {
    loadScript('Foo.js',bar);
} else {
    bar();
}

答案 2 :(得分:0)

根据seanmonstar的回答,我发现此异步/等待解决方案可以很好地工作。如果脚本先前已加载过,它将立即解析,或者一旦脚本下载后,它将立即解析。

static async loadScript(url){

    return new Promise( resolve => {

        const element = document.getElementById(url);

        if(element){
            resolve();
        }else{
            const script = document.createElement("script");

            script.id = url;

            script.onload = () => {
                resolve();
            };
            script.src = url;

            document.body.appendChild(script);
        }
    });

}

它的用法如下:

await loadScript("../libs/geopackage/geopackage.js");