2012-06-27 7 views
18

मैं एसिंक्रोनस-नेस के बारे में मूलभूत चीज़ को समझता हूं: चीजें अनुक्रमिक रूप से निष्पादित नहीं होती हैं। और मैं समझता हूं कि इसके बारे में कुछ बहुत शक्तिशाली है ... कथित तौर पर। लेकिन मेरे जीवन के लिए मैं कोड के चारों ओर अपने सिर लपेट नहीं सकता। आइए एसिंक नोड.जेएस कोड पर एक नज़र डालें जो मैंने लिखा है ... लेकिन वास्तव में नहीं मिलता है।लेमन के नियमों में असीमित कोड को समझना

function newuser(response, postData) { 
    console.log("Request handler 'newuser' was called."); 
    var body = '<html>' + 
     '<head>' + 
     '<meta http-equiv="Content-Type" content="text/html; ' + 
     'charset=UTF-8" />' + 
     '</head>' + 
     '<body>' + 
     '<form action=" /thanks" method="post">' + 
     '<h1> First Name </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<h1> Last Name </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<h1> Email </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<input type="submit" value="Submit text" />' + 
     '</body>' + 
     '</html>'; 
    response.writeHead(200, { "Content-Type": "text/html" }); 
    response.write(body); 
    response.end(); 
} 

प्रतिक्रिया फिर से कहां से आई? डाटा डालो? मैं इस "कॉलबैक" में एक चर को परिभाषित क्यों नहीं कर सकता और फिर इसे कॉलबैक के बाहर उपयोग कर सकता हूं? क्या कुछ चीजें अनुक्रमिक होने के लिए एक तरीका है तो शेष प्रोग्राम async?

उत्तर

41

मुझे यकीन नहीं है कि यह फ़ंक्शन कहां उपयोग किया जा रहा है, लेकिन कॉलबैक का बिंदु यह है कि आप उन्हें कुछ फ़ंक्शन में पास करते हैं जो असीमित रूप से चलता है; यह आपके कॉलबैक को दूर रखता है, और जब वह फ़ंक्शन जो कुछ भी करने की ज़रूरत होती है, उसके साथ किया जाता है, तो यह आवश्यक पैरामीटर के साथ कॉल कॉल करेगा। फ्रंट-टू-बैक का एक उदाहरण शायद सबसे अच्छा है।

कल्पना कीजिए कि हमारे पास एक ढांचा है, और इसमें एक ऑपरेशन है जो लंबे समय तक चलता है, डेटाबेस से कुछ डेटा लाता है।

function getStuffFromDatabase() { 
    // this takes a long time 
}; 

चूंकि हम इसे सिंक्रनाइज़ नहीं करना चाहते हैं, इसलिए हम उपयोगकर्ता को कॉलबैक में प्रवेश करने की अनुमति देंगे।

function getStuffFromDatabase(callback) { 
    // this takes a long time 
}; 

हम setTimeout के लिए एक कॉल के साथ एक लंबे समय लेने के अनुकरण करेंगे; हम यह भी दिखाएंगे कि हमें डेटाबेस से कुछ डेटा मिला है, लेकिन हम केवल स्ट्रिंग मान को हार्डकोड करेंगे।

function getStuffFromDatabase(callback) { 
    setTimeout(function() { 
    var results = "database data"; 
    }, 5000); 
}; 

अंत में, एक बार हम डेटा है, तो हम कॉल कॉलबैक ढांचे का कार्य उपयोगकर्ता द्वारा हमें दिए गए करेंगे।

function getStuffFromDatabase(callback) { 
    setTimeout(function() { 
    var results = "database data"; 
    callback(results); 
    }, 5000); 
}; 

ढांचे का एक उपयोगकर्ता के रूप में, आप समारोह का उपयोग करने के कुछ इस तरह करते हैं: तो

getStuffFromDatabase(function(data) { 
    console.log("The database data is " + data); 
}); 

, जैसा कि आप data (समान response के रूप में और अपने उदाहरण में postData) देख सकते हैं उस समारोह से आया है जिसे आपने अपना कॉलबैक में पास किया है; यह आपको वह डेटा देता है जब यह जानता है कि वह डेटा क्या होना चाहिए।

कारण आप अपने कॉलबैक में कोई मूल्य निर्धारित नहीं कर सकते हैं और कॉलबैक के बाहर इसका उपयोग कर सकते हैं क्योंकि बाद में कॉलबैक स्वयं नहीं होता है।

// executed immediately executed sometime in the future 
//  |     |  by getStuffFromDatabase 
//  v     v 
getStuffFromDatabase(function(data) { 
    var results = data; // <- this isn't available until sometime in the future! 
}); 

console.log(results); // <- executed immediately 

जब console.log रन var results का काम अभी तक नहीं हुई!

1) async की शक्ति एक साथ कई काम करने के लिए सक्षम किया जा रहा है मुख्य थ्रेड पर ताला लगा के बिना:

+0

तकनीकी बिंदु से आप सही हैं, लेकिन जो आपने याद किया वह था "आप पहली जगह में कॉलबैक क्यों करना चाहते हैं"। यही कारण है कि एसिंक इतना महत्वपूर्ण बनाता है। – jcolebrand

+3

मैं यह नहीं कहूंगा कि मैंने इसे एक या दो बार पढ़ा नहीं होगा - लेकिन शायद यह सबसे अच्छा स्पष्टीकरण है जो शारीरिक रूप से यहां दिए बिना दे सकता है, हे। – PinkElephantsOnParade

+1

मुझे लगता है कि कॉलबैक कैसे काम करता है यह समझने के लिए यह एक महान स्पष्टीकरण है - इसके लिए धन्यवाद! – wmock

6

आप यहाँ कई असंबंधित प्रश्न हैं। सामान्य रूप से नोड और जेएस में, यह विशेष रूप से AJAX फ़ाइल अनुरोधों पर लागू होता है। इसका मतलब यह है कि मैं फ़ाइलों को पुनः प्राप्त करने के लिए कई एसिंक कॉलों को बंद कर सकता हूं, और सामग्री को प्रस्तुत करते समय मुख्य थ्रेड को लॉक नहीं कर सकता। मेरा पसंदीदा ढांचा jQuery है, जिसमें सुविधाजनक $ है। यह पता चला है कि jQuery उपयोग के लिए एसिंक कॉल को लपेटता है और मानकीकृत करता है।

2) प्रतिक्रिया और पोस्टडेटा माता-पिता विधि से आती है। यहाँ जादुई कुछ भी नहीं है, यह एक सामान्य फंक्शन कॉल है, इसलिए इनके मूल्य कहीं और बनाए जाते हैं और इस आमंत्रण में पारित होते हैं। आपके पास कौन सा नोड ढांचा है, इस पर निर्भर करता है कि आपकी विधि का सटीक हस्ताक्षर बदल जाएगा।

3) यदि आप ठीक से स्कॉप्ड हैं तो आप अपने कॉलबैक में एक वैश्विक चर परिभाषित कर सकते हैं। ऐसा प्रतीत होता है कि आपको सीखने में मदद की ज़रूरत है कि कौन सा गुंजाइश है। ये कुछ लिंक

http://www.digital-web.com/articles/scope_in_javascript/

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

4) एक बार जब आप async जाओ, तुम वापस कभी नहीं जा सकते हैं, हालांकि, वादा लाभ उठाकर और आस्थगित वस्तुओं की तरह jQuery Deferreds के साथ करने के लिए कई asyncs लिए प्रतीक्षा कर सकते हैं अभी तक एक और async में अपने निष्पादन जारी रखने से पहले पूरा करें। Deferreds आपके दोस्त हैं।

http://api.jquery.com/category/deferred-object/

+0

किसी भी तरह से इस बार मेरे द्वारा देखे जाने वाले इस बहुत अच्छे उत्तर को याद किया: +1 – PinkElephantsOnParade

+0

ठीक है आपने किया था। मैं गज़ब हूँ! –

+2

मैं आपके आत्मविश्वास की सराहना करता हूं – PinkElephantsOnParade

1

ऐसा लगता है आप Node Beginner Book के माध्यम से काम कर रहे हैं। मैं आपको पूरी किताब के माध्यम से काम करने के लिए प्रोत्साहित करता हूं, यह वास्तव में एक उत्कृष्ट परिचय है। यदि आप जावास्क्रिप्ट को बेहतर ढंग से समझने की कोशिश कर रहे हैं, तो यूट्यूब पर डगलस क्रॉकफोर्ड के वीडियो एक महान अवलोकन हैं: 1, 2

आपके द्वारा पोस्ट किए गए कोड का टुकड़ा मेरे लिए वास्तव में आपकी सहायता करने के लिए पर्याप्त संदर्भ नहीं है। response एक पैरामीटर है जिसे आप अपने फ़ंक्शन पर भेज रहे हैं, यह पोस्टडेटा से नहीं आता है। यदि आप कोड के साथ काम कर रहे हैं जिस तरह से नोड शुरुआती पुस्तक सुझाती है, तो संभवतया आप CreateServer फ़ंक्शन से नीचे अपने नए उपयोगकर्ता फ़ंक्शन को प्रतिक्रिया दे रहे हैं, जो नोड के साथ आने वाले http मॉड्यूल का हिस्सा है।

आप कॉलबैक में एक चर परिभाषित नहीं कर सकते हैं और फिर कॉलबैक में इसका उपयोग कर सकते हैं क्योंकि जावास्क्रिप्ट को स्पष्ट रूप से स्कॉप्ड किया गया है। जावास्क्रिप्ट के दायरे के विषय पर Stack Overflow post है। मैंने पोस्ट किए गए डौग क्रॉकफोर्ड द्वारा पहला वीडियो जावास्क्रिप्ट के स्कॉइंग नियमों का एक बड़ा स्पष्टीकरण भी है।

जावास्क्रिप्ट आवश्यक रूप से async नहीं है। यह केवल अज्ञात कार्यों को प्रदान करता है जो बंद होते हैं, जो एसिंक तर्क को आसानी से कार्यान्वित करने के लिए उपयोगी उपकरण हैं। दोबारा, नोड शुरुआती पुस्तक नोड के साथ सिंक्रोनस कोड लिखने का एक अच्छा उदाहरण दिखाती है (जो आप चाहते हैं), फिर इसे एसिंक बनाने के लिए इसे फिर से लिखना।

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