अगले समारोह को व्यक्त करें, यह वास्तव में किस लिए है?


124

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

जवाबों:


161

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

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

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() {
  //...
});

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

8
@AndreasSelenwall next('route')विशिष्ट है app.VERB()और इसका उपयोग तब किया जाता है जब किसी मार्ग में एकाधिक कॉलबैक " शेष मार्ग कॉलबैक (ओं) को बायपास करें। " next(err)का उपयोग किसी भी " त्रुटि मिडलवेयर " ( Eपोस्ट से) में कूदने के लिए किया जाता है ।
जोनाथन लोनोस्की

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

8
next()बिना किसी तर्क के कॉल करना वास्तव में सिस्टम को "मैं इसे संभालना नहीं चाहता" बताता हूं, यह सिर्फ सिस्टम को बताता है कि यह एक के बाद किसी भी शेष बिचौलियों को संसाधित करना जारी रखेगा। यह कॉल करने के लिए कोई त्रुटि स्थिति नहीं है next(), यह सामान्य प्रवाह का हिस्सा है। यदि आप कॉल next()नहीं करते हैं तो अन्य मार्गों को बिल्कुल भी संसाधित नहीं किया जाएगा।
d512

1
काश, इस वेबसाइट पर और अधिक उत्तर आम आदमी के लिए लिखे होते ... '' अगला () बिना किसी तर्क के कहता है, '' सिर्फ मजाक कर रहा हूं, मैं वास्तविक रूप से इसे संभालना नहीं चाहता '' - नोब्स के लिए बिल्कुल सही ... (@ d512 has a हालांकि बेहतर व्याख्या)
दाकोडा

129

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

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

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

यहाँ छवि विवरण दर्ज करें

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

तो आगे क्या करता है? सरल, यह आपके ऐप को अगले मिडलवेयर को चलाने के लिए कहता है। लेकिन तब क्या होता है जब आप अगले कुछ पास करते हैं? एक्सप्रेस वर्तमान स्टैक को समाप्त कर देगा और सभी मिडलवेयर चलाएगा जिसमें 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 एप्लिकेशन को एक स्टैक के रूप में चित्रित करते हैं, तो आप शायद स्वयं बहुत अजीबता को ठीक करने में सक्षम होंगे। उदाहरण के लिए जब आप अपने राउटर मिडलवेयर को राउटर के बाद जोड़ते हैं तो यह समझ में आता है कि आपके मार्गों में कुकीज़ नहीं हैं।


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

"एक्सप्रेस वर्तमान स्टैक को समाप्त कर देगा और सभी मिडलवेयर चलाएगा जिसमें 4 पैरामीटर हैं।" मैं सोच रहा था कि एक्सप्रेस कैसे सटीक त्रुटि हैंडलर मिडलवेयर चलाने में सक्षम है। धन्यवाद!
अभिषेक अग्रवाल

75

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

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

आप इस प्रिंट को कंसोल में देखेंगे:

before request handler
handling request
after request handler

अब अगर आप next()बीच हैंडलर में इस तरह से कॉल को कमेंट करते हैं :

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 लौटाता है) सफल था या नहीं, यदि आप चाहते हैं कि बाकी के बिचौलिये भी चलें तो आपको कॉल करना होगा 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()पहले हैंडलर में कॉल करना होगा ।

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


सोनफ़र मेरे लिए सबसे अच्छा जवाब।
नोरयार घूमसैन

अच्छी तरह से स्पष्टीकरण!
चांग

7

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


2
या अगला मिडिलवेयर।
रॉबर्टक्लेप


1

ऊपर कॉल को अगले पर ध्यान दें ()। इस फ़ंक्शन को कॉल करना ऐप में अगले मिडलवेयर फ़ंक्शन को आमंत्रित करता है। अगला () फ़ंक्शन Node.js या Express API का हिस्सा नहीं है, लेकिन तीसरा तर्क है जो मिडलवेयर फ़ंक्शन को दिया जाता है। अगले () फ़ंक्शन को कुछ भी नाम दिया जा सकता है, लेकिन सम्मेलन द्वारा, इसे हमेशा "अगला" नाम दिया जाता है। भ्रम से बचने के लिए, हमेशा इस सम्मेलन का उपयोग करें।


0

अगले ('मार्ग') के उपयोग के बारे में पूछे गए प्रश्न, जो अब तक दिए गए उत्तरों में सप्ताह को कवर करने के लिए लगता है:

  1. अगले का उपयोग ():

संक्षेप में: अगले मिडलवेयर फ़ंक्शन।

इस आधिकारिक एक्सप्रेस जेएस प्रलेखन - 'लेखन-मिडलवेयर' पृष्ठ से निकालें :

"मिडिलवेयर फ़ंक्शन myLogger बस एक संदेश प्रिंट करता है, फिर अगले () फ़ंक्शन को कॉल करके स्टैक में अगले मिडलवेयर फ़ंक्शन के अनुरोध पर गुजरता है ।"

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

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

एक्सप्रेस जेएस प्रलेखन का यह पृष्ठ बताता है "यदि वर्तमान मिडलवेयर फ़ंक्शन अनुरोध-प्रतिक्रिया चक्र को समाप्त नहीं करता है, तो उसे अगले मिडलवेयर फ़ंक्शन पर नियंत्रण पास करने के लिए अगले () कॉल करना होगा। अन्यथा, अनुरोध लटका हुआ रह जाएगा।"

  1. अगले का उपयोग ('मार्ग'):

संक्षेप में: अगला मार्ग (बनाम अगले के मामले में अगले मिडलवेयर फ़ंक्शन )

इस एक्सप्रेस जेएस प्रलेखन से निकालें - 'उपयोग-मिडलवेयर' पेज :

"राउटर मिडलवेयर स्टैक से मिडलवेयर फ़ंक्शंस के बाकी हिस्सों को छोड़ने के लिए, अगले रूट पर कंट्रोल पास करने के लिए नेक्स्ट ('रूट') को कॉल करें । नोट: नेक्स्ट ('रूट') मिडिलवेयर फ़ंक्शंस में ही काम करेगा, जिन्हें इस्तेमाल करके लोड किया गया था। app.METHOD () या राउटर। METHOD () फ़ंक्शन।

यह उदाहरण एक मिडलवेयर सब-स्टैक दिखाता है जो GET के अनुरोधों को / user /: id पथ को संभालता है। "

app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route
  if (req.params.id === '0') next('route')
  // otherwise pass the control to the next middleware function in this stack
  else next()
}, function (req, res, next) {
  // render a regular page
  res.render('regular')
})

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
  res.render('special')
})

0

अगले () req के साथ मिडलवेयर फ़ंक्शन के लिए कॉलबैक तर्क है, और नीचे दिए गए कोड में अगले के लिए http अनुरोध और प्रतिक्रिया तर्क दिया जा रहा है।

app.get ('/', (req, res, next) => {अगला ()});

तो अगला () मिडलवेयर फ़ंक्शन में पारित कॉल करता है। यदि वर्तमान मिडलवेयर फ़ंक्शन अनुरोध-प्रतिक्रिया चक्र को समाप्त नहीं करता है, तो उसे अगले कॉल करना चाहिए (), अन्यथा अनुरोध लटका हुआ रहेगा और समय समाप्त हो जाएगा।

अगले () fn को प्रत्येक मिडलवेयर फ़ंक्शन के भीतर बुलाया जाना चाहिए, जब कई मिडलवेयर फ़ंक्शंस app.use या app.METHOD को पास किए जाते हैं, अन्यथा अगले मिडलवेयर फ़ंक्शन को नहीं बुलाया जाएगा (1 से अधिक मिडलवेयर फ़ंक्शंस पारित किए जाते हैं)। शेष मिडलवेयर फ़ंक्शंस को कॉल करने के लिए, मिडिलवेयर फ़ंक्शन के भीतर अगला ('मार्ग') कॉल करें जिसके बाद किसी अन्य मिडलवेयर फ़ंक्शंस को नहीं बुलाया जाना चाहिए। नीचे दिए गए कोड में, fn1 को कॉल किया जाएगा और fn2 को भी बुलाया जाएगा, क्योंकि अगला () fn1 के भीतर कहा जाता है। हालाँकि, fn3 को कॉल नहीं किया जाएगा, क्योंकि अगला ('मार्ग') fn2 के भीतर कहा जाता है।

app.get('/fetch', function fn1(req, res, next)  {
console.log("First middleware function called"); 
    next();
}, 
function fn2(req, res, next) {
    console.log("Second middleware function called"); 
    next("route");
}, 
function fn3(req, res, next) {
    console.log("Third middleware function will not be called"); 
    next();
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.