2013-03-22 12 views
7

Ho scritto un middleware per Connect and Express che richiede un notevole sollevamento nel suo metodo di installazione. A causa della natura delle attività di inizializzazione, questa roba è asincrona, quindi ho il problema che il middleware deve essere accessibile solo dopo aver eseguito l'inizializzazione.Come utilizzare l'inizializzazione asincrona in un middleware Connect?

Attualmente ho risolto utilizzando un callback:

function setupMiddleware(callback) { 
    doSomeAsyncInitialization(function() { 
    callback(function (req, res, next) { 
     // The actual middleware goes here ... 
    }); 
    }); 
} 

Questo funziona, ma non è bello per il chiamante. Invece di essere in grado di fare

app.use(setupMiddleware()); 

che devo fare:

setupMiddleware(functin (middleware) { 
    app.use(middleware); 
}); 

Ora stavo pensando se vi sia un approccio migliore, per esempio lasciare che il middleware inizializzi in background e ritardare tutte le richieste in arrivo fino a quando il middleware è pronto.

Come posso risolvere questo? Qualche idea o best practice che dovrei usare qui?

risposta

2

ora risolto utilizzando una variabile isInitialized e ritardando la funzione middleware stesso. Vedere il seguente esempio:

var connect = require('connect'); 

var setup = function() { 
    var isInitialized = false; 

    setTimeout(function() { 
    isInitialized = true; 
    }, 10000); 

    function run (req, res, next) { 
    res.write('Foo'); 
    res.end(); 
    } 

    function delay (req, res, next) { 
    if (isInitialized) { 
     return run(req, res, next); 
    } 

    setTimeout(function() { 
     delay(req, res, next); 
    }, 1000); 
    } 

    return function (req, res, next) { 
    if (req.url === '/foo') { 
     delay(req, res, next); 
     return; 
    } 
    next(); 
    } 
}; 

var app = connect(); 
app.use(setup()); 
app.use(function (req, res) { 
    res.write('Fertig!'); 
    res.end(); 
}); 

var http = require('http'); 

http.createServer(app).listen(5000); 

prega di notare che questo codice non è stato ottimizzato o riscritta in qualsiasi modo, è solo una dimostrazione che l'idea stessa funziona.

0

Perché non fai come i seguenti,

doSomeAsyncInitialization(function() { 
    //After doing all long running init process just configure your express as follows. 
    app.use(<middlewares>); 
    app.listen(<portnumder>); 

}); 
+1

Poiché l'inizializzazione è solo per un middleware, non per l'intera app. E questo schema ovviamente funziona, ma non è "bello". Non mi piace che tutto sia rientrato di un passo (e questo non è solo un problema di formattazione ;-)). –

+0

Lo accetto. Dato che Nodejs non è bloccante, devi ottenere il codice nella callback del processo in esecuzione prolungata o nel modo mostrato nella tua domanda. Ofcource, puoi usare un modulo asincrono. Qui ho presupposto che il tuo middleware sia obbligatorio per tutte le richieste, in modo da mantenere la funzione app.use(). E il mio suggerimento è, basta inizializzare il middleware prima di iniziare ad ascoltare la porta. Se ti aspetti più della formattazione, devo capire cosa sta succedendo nella funzione "doSomeAsyncInitialization". –

+0

Bene, come detto, un'idea potrebbe essere che la funzione di configurazione restituisca immediatamente il middleware, ma che il middleware ritardi le richieste in arrivo fino a quando non è stato completamente inizializzato. –

Problemi correlati