2010-12-05 32 views
18

मैं एक अनुभवी सॉफ्टवेयर डेवलपर हूं, लेकिन जेएस और नोड के लिए काफी नया है। मैं सुपर-नेस्टेड कोड का बड़ा प्रशंसक नहीं हूं, इसलिए मैं कॉलबैक को अपने कार्यों में तोड़ने की कोशिश कर रहा हूं। कॉलबैक आग लगने पर गुंजाइश को बनाए रखने के तरीके के बारे में मुझे परेशानी हो रही है। चारों ओर खोदने से मैंने पढ़ा कि अगर मैंने कॉलबैक पर बंद कर दिया तो यह काम करेगा, लेकिन ऐसा लगता है कि जिस तरह से मैं उम्मीद करता हूं वह काम नहीं करता है।मैं node.js कॉलबैक में दायरा कैसे बनाए रख सकता हूं?

function writeBody() 
{ 
    res.end("<h1> Hooray! </h1>"); 
} 

http.createServer(function(req, res) 
{ 
    res.writeHead('Content-Type', 'text/html'); 
    setTimeout(function(){writeBody()}, 2000); 
}).listen(8000); 

मैंने सोचा था कि समारोह() बंद में writeBody() कॉल लपेटकर द्वारा मैं गुंजाइश होगा:

यहाँ कोड की तरह है कि मेरे लिए काम नहीं कर रहा है की एक बहुत ही सरल संस्करण है मैं समय समाप्ति के बाद की जरूरत है, लेकिन मैं

ReferenceError: res is not defined

किसी को भी मुझे बता सकते हैं क्या boneheaded बात मैं गलत कर रहा हूँ जब writeBody() आग?

उत्तर

35

असल में यह नहीं कि काम बंद करने के तरीके, कार्यों को उनके बाहरी क्षेत्रों का वारिस मिलता है, यह इस तरह काम करता है।

// this function only inherits the global scope 
function writeBody() 
{ 
    res.end("<h1> Hooray! </h1>"); 
} 

http.createServer(function(req, res) // a new local varaible res is created here for each callback 
{ 
    res.writeHead('Content-Type', 'text/html'); 
    // annonymous function inheris both the global scope 
    // as well as the scope of the server callback 
    setTimeout(function(){ 

     // the local variable res is available here too 
     writeBody() 

    }, 2000); 
}).listen(8000); 

यह सिर्फ काम समारोह में res वस्तु गुजरती हैं, के रूप में यह समय समाप्ति कॉलबैक में उपलब्ध है बनाने के लिए।

function writeBody(res) 
{ 
    // NOT the same variable res, but it holds the same value 
    res.end("<h1> Hooray! </h1>"); 
} 

http.createServer(function(req, res) 
{ 
    res.writeHead('Content-Type', 'text/html'); 
    setTimeout(function(){ 
     writeBody(res); // just pass res 
    }, 2000); 
}).listen(8000); 

लेकिन आप इस जैसी चीजों के लिए बाहर देखने की जरूरत है:

for(var i = 0; i < 10; i++) { // only one i gets created here!() 
    setTimeout(function() { 
     console.log(i); // this always references the same variable i 
    }, 1000); 
} 

यह 10 दस बार प्रिंट होगा, क्योंकि संदर्भ में ही है और i10 करने के लिए सभी तरह से ऊपर की संख्या बढ़ जाती है। यदि आप अलग-अलग संख्याएं चाहते हैं तो आपको प्रत्येक के लिए एक नया चर बनाने की आवश्यकता है, या तो setTimeout को एक अज्ञात स्वयं फ़ंक्शन में लपेटकर, जिसे आप पैरामीटर के रूप में i में पास करते हैं, या किसी अन्य विधि को कॉल करके टाइमआउट सेट करते हैं और पैरामीटर के रूप में i प्राप्त करता है।

// anoynmous function version 
for(var i = 0; i < 10; i++) { 
    (function(e){ // creates a new variable e for each call 
     setTimeout(function() { 
      console.log(e); 
     }, 1000); 
    })(i); // pass in the value of i 
} 

// function call version 
for(var i = 0; i < 10; i++) { 
    createTimeoutFunction(i); 
} 
+0

ओह! ओह! * फेसपाल्म * यह एक टन में मदद करता है, मेरे दिमाग में बस एक शिफ्ट-आई पल था। – MahatmaManic

2

तुम भी कार्यों नेस्ट हालांकि इसका मतलब है कि कर सकते हैं, तो वे गुंजाइश साझा करते हैं, यानी

http.createServer(function(req, res) 
{ 

    function writeBody() 
    { 
     res.end("<h1> Hooray! </h1>"); 
    } 

    res.writeHead('Content-Type', 'text/html'); 
    setTimeout(function(){writeBody()}, 2000); 
}).listen(8000); 

मैं अक्सर लगता है यह हमेशा में चर का एक समूह गुजर दायरे में रखने के लिए की तुलना में आसान है, आप कहीं और फ़ंक्शन का पुन: उपयोग नहीं कर सकते हैं।

+1

मैं जवाब देने का समय लेने की सराहना करता हूं, और आप शायद सही हैं कि यह अक्सर तेज़ और आसान होता है, लेकिन शैली के सामान्य नियम के रूप में मैं घोंसले से बचने की कोशिश करता हूं जहां मैं कर सकता हूं। इस सरल उदाहरण में यह इतना बुरा नहीं है, लेकिन जब चीजें अधिक जटिल होती हैं (जैसे फाइलें ढूंढना, पढ़ना और प्रसंस्करण करना) यह बदसूरत तेज़ हो जाता है। – MahatmaManic

+0

मैं इस शैली को पसंद करता हूं। एक उत्तर पोस्ट किया जो इस अवधारणा पर फैलता है। – rocketsarefast

0

आप तो अपने कॉलबैक में प्रतिक्रिया पारित कर सकते हैं:

http.createServer(function(req, res) 
{ 
    res.writeHead('Content-Type', 'text/html'); 
    setTimeout(function(){writeBody(res)}, 2000); 
}).listen(8000); 
0

मैं वास्तव में जस्टिन Cormack के जवाब की तरह। मेरा हालिया कोडिंग का एक और चरम उदाहरण यहां दिया गया है।

var Func4 = function(req, res) 
{ 
    var collectionName = "parts"; 
    var f0 = function() {mongodbClient.collection(collectionName, f1);}; 
    var f1 = function(err, coll) {coll.ensureIndex("item", f2);}; 
    var f2 = function(err, indexname) 
    { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    res.write("index name = " + indexname); 
    res.end(); 
    }; 
    f0(); 
}; 

अधिकांश लोग मुझे बताएंगे (और वे करते हैं) कि यह कोड लिखने का सही तरीका है।

var Func4 = function(req, res) 
{ 
    var collectionName = "parts"; 
    mongodbClient.collection(collectionName, function(err, coll) { 
    coll.ensureIndex("item", function(err, indexname) { 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.write("index name = " + indexname); 
     res.end(); 
    })}); 
}; 

शायद मैं एक n00b हूँ, लेकिन मैं नेस्टेड कॉलबैक थोड़ा कठिन पालन करने के लिए लगता है। मैं भी f0, f1, f2 फ़ंक्शंस का एक गुच्छा स्वीकार करता हूं। किसी भी तरह से, यह गुंजाइश का एक अच्छा उदाहरण है।

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

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