2013-05-29 9 views
66

Scenario: Si consideri quanto segue è la parte del codice da un'app Web del nodo.Quando utilizzare next() e return next() in Node.js

app.get('/users/:id?', function(req, res, next){ 
    var id = req.params.id; 
    if (id) { 
     // do something 
    } else { 
     next(); //or return next(); 
    } 
}); 

Problema: Sto controllando quale andare con appena next() o return next(). Sopra codice di esempio funziona esattamente lo stesso per entrambi & non ha mostrato alcuna differenza nell'esecuzione.

Domanda: Qualcuno può mettere luce su questo, quando usare next() e quando utilizzare return next() e alcune importanti differenze?

risposta

63

Alcune persone scrivono sempre return next() per garantire che l'esecuzione si interrompa dopo l'attivazione della richiamata.

Se non lo fai, rischi di attivare la richiamata una seconda volta dopo, il che di solito ha risultati devastanti. Il tuo codice va bene così com'è, ma vorrei riscrivere come:

app.get('/users/:id?', function(req, res, next){ 
    var id = req.params.id; 

    if(!id) 
     return next(); 

    // do something 
}); 

me Si salva un livello di rientro, e quando ho letto il codice in un secondo momento, sono sicuro che non c'è modo next viene chiamato due volte .

35

next() è parte di connect middleware. Le callback per il flusso del router non si preoccupano se si restituisce qualcosa dalle proprie funzioni, quindi return next() e next(); return; è praticamente lo stesso.

Nel caso in cui si desidera interrompere il flusso di funzioni che è possibile utilizzare next(err) come il seguente

app.get('/user/:id?', 
    function(req, res, next) { 
     console.log('function one'); 
     if (!req.params.id) 
      next('No ID'); // This will return error 
     else 
      next(); // This will continue to function 2 
    }, 
    function(req, res) { 
     console.log('function two'); 
    } 
); 

Praticamente next() viene utilizzato per estendere il middleware delle vostre richieste.

+0

Possiamo inviare parametri come: 'next ('No ID')'? –

+5

'next ('No ID')' sta effettivamente inviando un errore, che interromperà il flusso. – drinchev

+0

Usa next (null, "somevalue"); Per strumenti come async.waterfall passerà il valore alla funzione successiva. Per serie complesse di interazioni che sono guidate dai dati, di solito passo un oggetto di contesto tra le funzioni. In questo modo posso creare funzioni generiche che possono essere condivise tra più end point e controllare il flusso tramite i dati nel contesto –

28

Come risposta di @Laurent Perrin:

Se non lo fai, si rischia di innescare la richiamata una seconda volta dopo, che di solito ha risultati devastanti

faccio un esempio qui se si scrive middleware in questo modo:

app.use((req, res, next) => { 
    console.log('This is a middleware') 
    next() 
    console.log('This is first-half middleware') 
}) 

app.use((req, res, next) => { 
    console.log('This is second middleware') 
    next() 
}) 

app.use((req, res, next) => { 
    console.log('This is third middleware') 
    next() 
}) 

scoprirete che l'uscita in console è:

This is a middleware 
This is second middleware 
This is third middleware 
This is first-half middleware 

Cioè, esegue il codice seguente next() dopo che tutta la funzione middleware è stata completata.

Tuttavia, se si utilizza return next(), verrà immediatamente richiamata la richiamata e il codice sotto return next() nella richiamata non sarà raggiungibile.

+1

Come principiante di 'express' questa risposta mi ha chiarito meglio delle altre risposte. Pollice su! – mandarin