14 Stimmen

Asynchrones Laden von JavaScript-Dateien mit Rückruf

Ich versuche, eine ultra einfache Lösung zu schreiben, um ein Bündel von JS-Dateien asynchron zu laden. Ich habe das folgende Skript unten so weit. Allerdings wird der Callback manchmal aufgerufen, wenn die Skripte nicht wirklich geladen sind, was zu einem Fehler "Variable nicht gefunden" führt. Wenn ich die Seite aktualisieren manchmal es funktioniert einfach, weil ich denke, die Dateien kommen direkt aus dem Cache und sind daher dort schneller als der Callback aufgerufen wird, es ist sehr seltsam?

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);
    }
}

Gibt es irgendwie zu testen, dass eine JS-Datei vollständig geladen wird, ohne etwas in die eigentliche JS-Datei selbst, weil ich möchte das gleiche Muster verwenden, um Bibliotheken außerhalb meiner Kontrolle (GMaps usw.) zu laden.

Aufrufender Code, direkt vor dem Tag.

var l = new Loader();
l.require([
    "ext2.js",
    "ext1.js"], 
    function() {
        var config = new MSW.Config();
        Refraction.Application().run(MSW.ViewMapper, config);
        console.log('All Scripts Loaded');
    });

Danke für jede Hilfe.

4voto

Caolan Punkte 3889

Nur für den Fall, dass Sie dies nützlich finden, habe ich ein asynchrones Dienstprogramm Bibliothek, die Sie den obigen Code als schreiben würde erstellt:

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);
    }
}

Wenn Sie viele asynchrone Anrufe tätigen, bietet es einige sehr leistungsstarke Funktionen :)

http://caolanmcmahon.com/async.html

4voto

Rajesh Shelar Punkte 51

Was ist mit jQuery....

$.getScript('abc.js'); 

Der obige Code lädt die Skriptdatei "abc.js" asynchron....

3voto

Pablo Moretti Punkte 1344

Ich empfehle Ihnen, ein kleines Lade-Javascript wie JcorsLoader zu verwenden (nur 647B mit Gzip)

JcorsLoader.load(
                "http://xxxx/jquery.min.js",
                function() {
                    $("#demo").html("jQuery Loaded");
                },
                "http://xxxx/jquery.cookie.js",
                function() {  
                    $.cookie('not_existing'); 
                }
            );

Mehrere js parallel laden und in der Reihenfolge ausführen, ohne DOMReady oder onload zu blockieren.

https://github.com/pablomoretti/jcors-loader

2voto

Aaron Butacov Punkte 28433

Es gibt nichts falsch mit Ihrem Code, was ich sagen kann, ist dies nur ein Fehler in Chrome (es tut es mit window.onload auch.)

Ich würde es der Funktion hinzufügen, die in der "load"-Funktion ausgelöst wird. Wenn die Variable vorhanden ist, führen Sie den JS-Code aus, aber wenn nicht, verwenden Sie ein setTimeout, um in 500ms oder so erneut zu prüfen.

0voto

Plokko Punkte 545

Wie Aaron sagt, gibt es einen Fehler in Chrome, aber es gibt auch Probleme mit dem IE und anderen Browsern.

Ich habe verschiedene Methoden ausprobiert, um meinen Lazy Loader zu erstellen und hatte eine Menge Probleme:

  • Hinzufügen eines <script>-Tags: Probleme mit Skriptereignissen (onload, onerror, etc.) im Explorer und anderen Browsern
  • Lesen eines Skripts mit Ajax und Parsen des Textes (mit eval, es ist javascript, also keine Sorge, es ist nicht evIl) : SEHR schwierig zu debuggen (es wird als eine einzige Zeile ohne Kommentare geparst, so dass Sie nicht wissen können, in welcher Zeile ein Fehler auftritt)
  • Lesen des Skripts mit Ajax und Hinzufügen eines <script>-Tags mit dem Text des Skripts: funktioniert sehr gut auf allen Browsern; Sie können async und sync Laden mit der gleichen Funktion zu erstellen und Sie können auch sehr gut kontrollieren, Fehler, Laden usw. (wenn Sie die Grundlagen der Ajax wissen, sollten Sie wissen, wie man variuous http Zustand zu behandeln) und es ist, was ich empfehlen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X