2012-10-30 17 views
77

next() विधि का एक अच्छा विवरण खोजने का प्रयास कर रहा है। एक्सप्रेस प्रलेखन में यह कहता है कि next('route') का उपयोग उस मार्ग पर कूदने के लिए और सभी मार्गों को बीच में छोड़ने के लिए किया जा सकता है, लेकिन कभी-कभी next को तर्क के बिना बुलाया जाता है। किसी को भी एक अच्छा ट्यूटोरियल आदि पता है जो next फ़ंक्शन का वर्णन करता है?अगले कार्य को व्यक्त करें, यह वास्तव में क्या है?

उत्तर

105

next() कोई तर्क नहीं कहता है "बस मजाक कर रहा हूं, मैं वास्तव में इसे संभालना नहीं चाहता हूं"। यह वापस चला जाता है और मैच के अगले मार्ग को खोजने का प्रयास करता है।

यह उपयोगी है, कहें कि क्या आप यूआरएल स्लग के साथ कुछ अन्य पेज मैनेजर चाहते हैं, साथ ही साथ कई अन्य चीजें भी हैं, लेकिन यहां एक उदाहरण है।

app.get('/:pageslug', function(req, res, next){ 
    var page = db.findPage(req.params.pageslug); 
    if (page) { 
    res.send(page.body); 
    } else { 
    next(); 
    } 
}); 

app.get('/other_routes', function() { 
    //... 
}); 

उस कोड को एक निश्चित आईडी स्लग वाले पृष्ठ के लिए डेटाबेस की जांच करनी चाहिए। अगर ऐसा लगता है कि कोई इसे प्रस्तुत करता है! अगर यह कोई नहीं मिलता है तो इस मार्ग हैंडलर को अनदेखा करें और अन्य लोगों की जांच करें।

तो next() कोई तर्क नहीं देता है कि आप मार्ग को संभाल नहीं पाएंगे ताकि कुछ और इसे उठा सके।


या app.all('*') के साथ एक हिट काउंटर। जो आपको कुछ साझा सेटअप कोड निष्पादित करने की अनुमति देता है और फिर कुछ और विशिष्ट करने के लिए अन्य मार्गों पर आगे बढ़ता है।

app.all('*', function(req, res, next){ 
    myHitCounter.count += 1; 
    next(); 
}); 

app.get('/other_routes', function() { 
    //... 
}); 
+0

शानदार उत्तर! मैंने अगले कुछ भी उपयोग देखा है, उदाहरण के लिए अगला (गलती) और अगला ('मार्ग')। क्या आप अब इनका उद्देश्य रखते हैं, आप एक त्रुटि का प्रचार कब करना चाहते हैं, और आप एक निश्चित मार्ग पर कब कूदना चाहेंगे? –

+7

@AndreasSelenwall 'अगला (' मार्ग ') '[app.VERB()'] (http://expressjs.com/api.html#app.VERB) के लिए विशिष्ट है और इसका उपयोग तब किया जाता है जब किसी रूट में एकाधिक कॉलबैक होते हैं "* शेष रूट कॉलबैक को बाईपास करें। *" अगला (गलती) 'किसी भी "[त्रुटि मिडलवेयर] (http://stackoverflow.com/a/7151775/15031)" ('E') पर कूदने के लिए प्रयोग किया जाता है पद से)। –

+2

उपरोक्त। बस इस वाक्यांश के लिए: "बस मजाक कर, मैं वास्तव में इसे संभालना नहीं चाहता" तुमने मुझे समझ लिया कि मैं क्या देख रहा था। मैंने बहुत सारे प्रश्न देखे, और एक वाक्यांश में समाधान मिला। –

102

अधिकांश ढांचे में आपको एक अनुरोध मिलता है और आप एक प्रतिक्रिया वापस करना चाहते हैं। Node.js की एसिंक प्रकृति की वजह से आप नेस्टेड कॉल बैक के साथ समस्याओं में भाग लेते हैं यदि आप गैर छोटी चीजें कर रहे हैं। इसे Connect.जेएस होने से रोकने के लिए (v4.0 से पहले, Express.js connect.js के शीर्ष पर एक परत थी) में ऐसा कुछ है जिसे मिडलवेयर कहा जाता है जो 2, 3 या 4 पैरामीटर वाला फ़ंक्शन होता है।

function (<err>, req, res, next) {} 

आपका Express.js ऐप इन कार्यों का ढेर है।

enter image description here

रूटर विशेष है, यह मिडलवेयर आप एक निश्चित यूआरएल के लिए एक या अधिक मिडलवेयर निष्पादित देता है कि है। तो यह एक ढेर के अंदर एक ढेर है।

तो अगला क्या करता है? सरल, यह आपके ऐप को अगले मिडलवेयर चलाने के लिए कहता है। लेकिन जब आप अगली चीज़ पास करते हैं तो क्या होता है? एक्सप्रेस वर्तमान स्टैक को रोक देगा और सभी पैरामीटर चलाएगा जिसमें 4 पैरामीटर होंगे।

function (err, req, res, next) {} 

यह मिडलवेयर किसी भी त्रुटि को संसाधित करने के लिए उपयोग किया जाता है। मुझे निम्नलिखित करना पसंद है:

next({ type: 'database', error: 'datacenter blew up' }); 

इस त्रुटि के साथ मैं शायद उपयोगकर्ता को कुछ गलत हो गया और वास्तविक त्रुटि लॉग इन कर दूंगा।

function (err, req, res, next) { 
    if (err.type === 'database') { 
    res.send('Something went wrong user'); 
    console.log(err.error); 
    } 
}; 

आप एक ढेर के रूप में अपने Express.js आवेदन चित्र तो आप शायद weirdness खुद का एक बहुत ठीक करने के लिए सक्षम हो जाएगा। उदाहरण के लिए जब आप राउटर के बाद अपना कुकी मिडलवेयर जोड़ते हैं तो यह समझ में आता है कि आपके मार्गों में कुकीज़ नहीं है।

+7

उत्कृष्ट उत्तर। –

+3

आप इस अनाम लॉगिंग फ़ंक्शन को कहां स्टोर करेंगे? – dennismonsewicz

5

पैरामीटर के बिना अगला() फ्रेमवर्क में अगले रूट हैंडलर को आमंत्रित करता है।

+0

या अगला मिडलवेयर। – robertklep

18

आईएमएचओ, इस प्रश्न का स्वीकार्य उत्तर वास्तव में सटीक नहीं है। जैसा कि अन्य ने कहा है, यह वास्तव में नियंत्रण के बारे में है जब श्रृंखला में अगला हैंडलर चलाया जाता है। लेकिन मैं इसे और अधिक ठोस बनाने के लिए थोड़ा और कोड प्रदान करना चाहता था। आप इस सरल एक्सप्रेस एप्लिकेशन है, कहते हैं:

before request handler 
handling request 
after request handler 

अब अगर आप में next() करने के लिए कॉल बाहर टिप्पणी:

var express = require('express'); 
var app = express(); 

app.get('/user/:id', function (req, res, next) { 
    console.log('before request handler'); 
    next(); 
}); 

app.get('/user/:id', function (req, res, next) { 
    console.log('handling request'); 
    res.sendStatus(200); 
    next(); 
}); 

app.get('/user/:id', function (req, res, next) { 
    console.log('after request handler'); 
    next(); 
}); 

app.listen(3000, function() { 
    console.log('Example app listening on port 3000!') 
}); 

यदि आप करते हैं

curl http://localhost:3000/user/123 

आप इस सांत्वना देने मुद्रित देखेंगे इस तरह के मध्य हैंडलर:

app.get('/user/:id', function (req, res, next) { 
    console.log('handling request'); 
    res.sendStatus(200); 
    //next(); 
}); 

आप कंसोल पर इस देखेंगे:

before request handler 
handling request 

सूचना है कि पिछले हैंडलर (एक है कि after request handler प्रिंट) नहीं चलता है। ऐसा इसलिए है क्योंकि अब आप अगले हैंडलर को चलाने के लिए व्यक्त नहीं कह रहे हैं।

तो यह वास्तव में यदि आपके "मुख्य" हैंडलर (एक है कि 200 रिटर्न) सफल या नहीं था, अगर आप middlewares के बाकी चलाना चाहते हैं कोई फर्क नहीं पड़ता, आप next() कॉल करनी होगी।

यह कब आसान होगा? आइए मान लें कि अनुरोध के सफल होने के बावजूद आप कुछ डेटाबेस में आने वाले सभी अनुरोधों को लॉग इन करना चाहते हैं।

app.get('/user/:id', function (req, res, next) { 
    try { 
     // ... 
    } 
    catch (ex) { 
     // ... 
    } 
    finally { 
     // go to the next handler regardless of what happened in this one 
     next(); 
    } 
}); 

app.get('/user/:id', function (req, res, next) { 
    logToDatabase(req); 
    next(); 
}); 

आप को चलाने के लिए दूसरे हैंडलर चाहते हैं, तो आपको पहले हैंडलर में next() कॉल करनी होगी।

याद रखें कि नोड एसिंक है इसलिए यह नहीं पता कि पहले हैंडलर का कॉलबैक कब समाप्त हो गया है। आपको next() पर कॉल करके इसे बताना होगा।

+0

यह वास्तव में एक स्पष्ट स्पष्टीकरण है। धन्यवाद। – swdon

संबंधित मुद्दे