2015-02-05 6 views
5

Io uso RequireJS per caricare i miei moduli in uno dei miei progetti. Vedo in rete diversi modi per richiedere moduli utilizzando la chiamata require (e non define).Quando RequireJS 'richiede una chiamata asincrona? Quando è sincrono?

Supponiamo che abbia un modulo denominato "JQuery" e vorrei richiederlo. Due modi sono possibili come ho visto negli esempi:

  1. questo:

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

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

La mia domanda è se il carico è asincrono come La documantazione di RequireJS dice che è, come può funzionare la seconda convenzione? Come posso dire con certezza che è stato definito $ e che la prima riga completata prima dell'esecuzione della seconda riga?

risposta

8

RequireJS carichi sempre moduli asincrono ma consentono una forma di require che sembra sincrono. Il tuo secondo frammento in realtà manca di codice veramente importante. (Inoltre, il nome del modulo per jQuery è codificato su jquery. È possibile scrivere una configurazione che consente di fare riferimento ad esso come jQuery ma non è necessario.) Questo modulo delle chiamate require è progettato per essere utilizzato all'interno dei moduli:

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

Cosa RequireJS fa con il codice di cui sopra è trasformarla in questa prima di eseguirlo:

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

nota l'aggiunta della dipendenza come primo argomento di define. Quando RequireJS esegue il codice, trova la dipendenza, carica jquery e quindi chiama la funzione anonima. Quando si incontra il numero require("jquery"), il modulo è già caricato. Alla fine della giornata mentre la chiamata requireha l'aspetto sincrono di, il caricamento del modulo che richiede avviene ancora in modo asincrono.

È possibile utilizzare questo modulo sincrono require all'esterno di una chiamata define? Solo se stai bene con i fallimenti. Questa chiamata require avrà esito negativo se il modulo passato non è già stata caricata. Si ottiene l'errore infame:

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

Usandolo in un define come ho mostrato sopra è sicuro.O Credo che si potrebbe fare:

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

che avrebbe lavoro, ma qual è il punto di ripetere manualmente la dipendenza. (Nel caso in cui ti chiedi, RequireJS non trasformare una chiamata require con un callback come quello che ho nel mio esempio qui nello stesso modo si trasforma un define chiamata come ho mostrato sopra.)

+0

grazie. ora è tutto chiaro, il codice sembra un po 'più bello e pulito nel secondo modo in cui lo vedo. :) – Er85

0

In base al file require.js, è un wrapper. Quindi sta ricostruendo il codice per funzionare in modo asincrono. Si chiama wrapper CommonJs. Potete trovare maggiori informazioni su di esso here

0

Non so requirejs. Ma penso che sia possibile caricare il modulo in entrambi i modi sync e async.

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