2015-02-05 15 views
5

Ich benutze RequireJS, um meine Module in einem meiner Projekte zu laden. Ich sehe im Internet verschiedene Möglichkeiten, um Module mit dem require Aufruf (und nicht define) erfordern.Wann benötigt RequireJS einen asynchronen Aufruf? Wann ist es synchron?

Lassen Sie uns annehmen, ich habe ein Modul namens "JQuery" und ich möchte es benötigen. Zwei Wege sind möglich, wie ich in den Beispielen gesehen:

  1. Dieses:

    require(["JQuery"], function($){ 
        $.doSomething(); 
    }) 
    
  2. Und:

    var $ = require("JQuery"); 
    $.doSomething(); 
    

Meine Frage ist, wenn die Last async als RequireJS Dokumantation sagt, es ist, wie kann die zweite Konvention funktionieren? Wie kann ich sicher sagen, dass $ definiert ist und die erste Zeile vor der zweiten Zeile ausgeführt wird?

Antwort

8

RequireJS lädt immer Module asynchron, aber es eine Form von require, die synchron aussieht ermöglichen. In Ihrem zweiten Snippet fehlt tatsächlich ein wirklich wichtiger Code. (Der Modulname für jQuery ist auch fest mit jquery codiert. Sie könnten eine Konfiguration schreiben, die Ihnen erlaubt, sie als jQuery zu bezeichnen, aber das hat keinen Sinn.) Diese Form der Aufrufe require ist so konzipiert, dass sie innerhalb von Modulen verwendet werden kann:

define(function (require) { 
    var $ = require("jquery"); 
    $.doSomething(); 
}); 

Was RequireJS mit dem Code tut oben ist es in diese Transformation vor der Ausführung:

define(['jquery'], function (require) { 
    var $ = require("jquery"); 
    $.doSomething(); 
}); 

Hinweis die Zugabe der Abhängigkeit als erstes Argument von define. Wenn RequireJS den Code ausführt, sucht er die Abhängigkeit, lädt jquery und ruft dann die anonyme Funktion auf. Wenn require("jquery") gefunden wird, ist das Modul bereits geladen. Am Ende des Tages, während der require Anruf sieht synchron, das Laden des Moduls, das es erfordert, geschieht immer noch asynchron.

Können Sie dieses synchrone Formular require außerhalb eines define Anrufs verwenden? Nur wenn Sie mit Fehlern einverstanden sind. Dieser Aufruf schlägt fehl, wenn das Modul nicht bereits geladen wurde. Sie die berüchtigte Fehlermeldung erhalten:

Module name ... has not been loaded yet for context: ... 

es in einem define Verwendung, wie ich oben gezeigt habe, ist sicher.Oder ich denke, man könnte tun:

require(['jquery'], function (require) { 
    var $ = require("jquery"); 
    $.doSomething(); 
}); 

die würde Arbeit, aber was ist der Sinn von manuell die Abhängigkeit zu wiederholen. (Falls Sie sich wundern, RequireJS nicht einen require Ruf mit einem Rückruf-Transformation, wie ich sie in meinem Beispiel haben hier in der gleichen Art und Weise es einen define Anruf verwandelt, wie ich habe oben gezeigt.)

+0

Ihnen danken. jetzt ist alles klar, der Code sieht ein bisschen schöner und sauberer in der zweiten Art aus, wie ich es sehe. :) – Er85

0

Laut require.js Dokumentation ist es ein Wrapper. Also wird Code neu aufgebaut, um asynchron zu arbeiten. Es heißt CommonJs Wrapper. Sie können mehr Informationen darüber finden here

0

Ich weiß nicht Requirejs. Aber ich denke, dass es möglich ist, Modul sowohl in sync als auch async Wege zu laden.

function require(name,cb){ 
    if(cb !== undefined){ 
     requireAsync(name,cb); 
    }else{ 
     requireSync(name); 
    } 
}