Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用回调异步加载JavaScript文件_Javascript_Ajax_Asynchronous_Design Patterns - Fatal编程技术网

使用回调异步加载JavaScript文件

使用回调异步加载JavaScript文件,javascript,ajax,asynchronous,design-patterns,Javascript,Ajax,Asynchronous,Design Patterns,我正在尝试编写一个超简单的解决方案来异步加载一堆JS文件。到目前为止,我有下面的脚本。但是,有时在脚本未实际加载时调用回调,这会导致变量未找到错误。如果我刷新页面,有时它只是工作,因为我猜文件直接来自缓存,因此比调用回调更快,这很奇怪吗 var Loader = function () { } Loader.prototype = { require: function (scripts, callback) { this.loadCount = 0;

我正在尝试编写一个超简单的解决方案来异步加载一堆JS文件。到目前为止,我有下面的脚本。但是,有时在脚本未实际加载时调用回调,这会导致变量未找到错误。如果我刷新页面,有时它只是工作,因为我猜文件直接来自缓存,因此比调用回调更快,这很奇怪吗

var Loader = function () {

}
Loader.prototype = {
    require: function (scripts, callback) {
        this.loadCount      = 0;
        this.totalRequired  = scripts.length;
        this.callback       = callback;

        for (var i = 0; i < scripts.length; i++) {
            this.writeScript(scripts[i]);
        }
    },
    loaded: function (evt) {
        this.loadCount++;

        if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call();
    },
    writeScript: function (src) {
        var self = this;
        var s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = src;
        s.addEventListener('load', function (e) { self.loaded(e); }, false);
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(s);
    }
}

谢谢您的帮助。

据我所知,您的代码没有任何问题,这只是Chrome中的一个bug(它也通过window.onload实现)


我会将其添加到“加载”函数中触发的函数中。如果变量存在,请执行JS代码,如果不存在,请使用setTimeout在500ms左右再次检查。

为了防止您发现这一点有用,我创建了一个异步实用程序库,可以让您将上述代码编写为:

var Loader = function () {}

Loader.prototype = {
    require: function (scripts, callback) {
        async.map(scripts, this.writeScript, callback);
    },
    writeScript: function(src, callback) {
        var s = document.createElement('script');
        s.type = "text/javascript";
        s.src = src;
        s.addEventListener('load', function (e) { callback(null, e); }, false);
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(s);
    }
}
如果您正在进行大量异步调用,它有一些非常强大的功能:)

关于jQuery

$.getScript('abc.js'); 

上面的代码将异步加载“abc.js”脚本文件……

就像Aaron说的chrome中有一个bug,但是IE和其他浏览器也有问题

我尝试了不同的方法来创建我的惰性加载程序,但我遇到了很多问题:

  • 添加标记:资源管理器和其他浏览器中的脚本事件(onload、onerror等)问题
  • 使用ajax阅读脚本并解析文本(使用eval,它是javascript,所以不用担心它不是邪恶的):调试非常困难(它被解析为一行,没有注释,所以您不知道哪行会出错)
  • 使用ajax阅读脚本并添加带有脚本文本的标记:在所有浏览器上都非常有效; 您可以使用相同的函数创建异步和同步加载,还可以很好地控制错误、加载等(如果您了解ajax的基础知识,您应该知道如何处理各种http状态),这就是我的建议

我建议您使用像JcorsLoader这样的小型javascript加载程序(只有647B和Gzip)

并行加载多个js并按顺序执行,而不阻塞DOMReady或onload


jcors-loader.js不在Internet Explorer中工作

Index.html

<html>
    <head>
    <script type="text/javascript" src="/js/jcors-loader.js"></script>
    <script>
        JcorsLoader.load(
                "js/jquery-1.8.0.js",
                "/js/alertme.js",
                function() {
                    $("#result").text("TEST OK");
                }
        );

    </script>
    </head>
    <body>
    <h1 id="result"></h1>
    </body>
    </html>

JcorsLoader.load(
“js/jquery-1.8.0.js”,
“/js/alertme.js”,
函数(){
$(“#结果”).text(“测试正常”);
}
);
alertme.js

警报(“已加载”)


这在chrome和firefox中运行良好,它显示“测试正常”和弹出窗口…但在IE(7,8,9)中没有消息或警报…任何帮助都将不胜感激

您在哪个浏览器和版本中测试此功能?在最新的WebKit中,是否也在最新的Chrome开发版本中进行了测试:(我无法使用Chrome 5.0.375.70复制此功能,从CDN加载两个脚本,从localhost加载一个脚本(包含在回调函数中执行一行所需的函数)。但是
async
标志真的有必要吗?如果你注释
s.async=true;
out会发生什么?是的,不需要真正的async。谢谢:)@galambalazs这个脚本是为一个移动web应用程序编写的,幸运的是没有问题:DYou也可以测试当前的函数:例如,如果你想以这种方式加载jQuery,您可以测试全局作用域中是否存在
$
函数:
如果(“$”在窗口中)/*执行某些操作*谢谢也添加了这个检查:)我已经在使用xui框架了,不想也包括jQuery框架,它只会增加额外的权重:)虽然我不知道jQuery可以做到这一点,谢谢
getScript
没有一个回调函数,该函数在脚本执行后调用。
JcorsLoader.load(
                "http://xxxx/jquery.min.js",
                function() {
                    $("#demo").html("jQuery Loaded");
                },
                "http://xxxx/jquery.cookie.js",
                function() {  
                    $.cookie('not_existing'); 
                }
            );
<html>
    <head>
    <script type="text/javascript" src="/js/jcors-loader.js"></script>
    <script>
        JcorsLoader.load(
                "js/jquery-1.8.0.js",
                "/js/alertme.js",
                function() {
                    $("#result").text("TEST OK");
                }
        );

    </script>
    </head>
    <body>
    <h1 id="result"></h1>
    </body>
    </html>