Come evitare schemi circolari nel nodo?

4

Sono nuovo di Node e JavaScript (beh, programmazione asincrona in generale) e ho notato quando stavo lavorando su un progetto che il codice seguente è un modello circolare e che queste sono pratiche sbagliate per l'ovvia ragione per cui il modulo potrebbe non essere ancora caricato (e il codice di esempio causa errori).

Ecco il mio codice:

Modulo principale

var module2 = require('./module2');

var data = 'data';

module2.fetchStuff(data);

Module2

var module3 = require('./module3');

var cleanDataArray = [];

function fetchStuff(data){
    // Fetches stuff based on data
    module3.cleanStuff(data);
}

function takeStuffBack(data){
    cleanData.push(data);
}

module.exports = {
    fetchStuff: fetchStuff,
    takeStuffBack: takeStuffBack,
    cleanData: cleanDataArray
};

Module3

var module2 = require('./module2');

function cleanStuff(data){
    // Clean data from needless stuff
    module2.takeStuffBack(data); // I get a TypeError here because 'module2' is yet to fully load.
}

module.exports = {
    cleanStuff: cleanStuff
};

Il XY

Ciò che questa struttura dovrebbe fare è che start module richiami una funzione di recupero in module2 , la funzione di recupero deve "lavare" i dati nel terzo modulo prima di riprenderli e fornirli per qualsiasi cosa desideri esportarlo. Quindi suppongo che XY sia che devo fare è ottenere dati da un'API di terze parti e quindi "pulire" i dati dalle cose che contiene ma non voglio, e quindi ho bisogno di fare quella versione "pulita" disponibile per il resto dell'applicazione.

Quali altri modi ci sono per farlo in un modo migliore, senza uno schema circolare come questo che è rotto perché module2 non verrà caricato prima che module3 provi a chiamarlo?

    
posta Gemtastic 03.08.2015 - 13:40
fonte

2 risposte

1

L'utilizzo di callback è il concetto più semplice da implementare da zero per piccoli scenari. Per i progetti a lungo termine, in genere vengono implementati Promises .

Bluebird è una libreria che ti dà loro. Sono stati anche aggiunti alle specifiche JavaScript, quindi forse ora sono accessibili in Node? (Scusate, la mia competenza principale è client JS). Per iniziare, verifica se la tua libreria asincrona effettiva può restituire promesse. In caso contrario, non dovrebbe essere difficile avvolgerlo con uno. In genere assomigliano a questo.

function PromiseWrapFunction() {
  return new Promise(success, fail) {
    libMethod.doThing({
      onSuccess: success,
      error: fail
    });
  });
}

Quindi, la maggior parte delle tue funzioni sarà simile a questa. Supponendo che non ti aspetti che la logica "onReturn" sia riusabile, puoi semplicemente utilizzare una funzione interna anonima piuttosto che nominarla.

function myAsyncFunction() {
  return myLibWrapper.PromiseWrapFunction().then(function(data) {
    var slightlyTransformedVersionOfData = {
      myVar: data.oldVar + 2
    };
    return slightlyTransformedVersionOfData;
  });
}

L'idea di base qui è che non puoi ancora restituire i dati finali, ma puoi restituire un oggetto che rappresenta i dati finali, e facilmente consentire a qualsiasi accessor di registrare i callback (usando .then( ). Il valore di ritorno di questo. Sarà un altro oggetto rappresentativo di questo tipo, ma il suo .then restituirà i dati modificati dalla richiamata. Le promesse sono un concetto ampio e questo è un riassunto molto veloce, quindi prova a trovare tutorial su di loro; di solito sono un ottimo modo per evitare schemi circolari come questi.

    
risposta data 01.12.2015 - 16:52
fonte
0

Utilizza un callback, passa takeStuffBack a cleanStuff mentre il callback prende i dati:

function cleanStuff(data, continuation){
    // Clean data from needless stuff
    continuation(data); 
}

fetchStuff nel modulo2 diventa:

function fetchStuff(data){
    // Fetches stuff based on data
    module3.cleanStuff(data, takeStuffBack);
}
    
risposta data 03.08.2015 - 13:57
fonte

Leggi altre domande sui tag