सादे अंग्रेजी में कॉलबैक की व्याख्या कैसे करें? वे दूसरे फ़ंक्शन से एक फ़ंक्शन को कॉल करने के फ़ंक्शन से कुछ संदर्भ लेते हुए कैसे भिन्न होते हैं? एक नौसिखिया प्रोग्रामर को उनकी शक्ति कैसे समझाई जा सकती है?
सादे अंग्रेजी में कॉलबैक की व्याख्या कैसे करें? वे दूसरे फ़ंक्शन से एक फ़ंक्शन को कॉल करने के फ़ंक्शन से कुछ संदर्भ लेते हुए कैसे भिन्न होते हैं? एक नौसिखिया प्रोग्रामर को उनकी शक्ति कैसे समझाई जा सकती है?
जवाबों:
अक्सर एक एप्लिकेशन को उसके संदर्भ / स्थिति के आधार पर विभिन्न कार्यों को निष्पादित करने की आवश्यकता होती है। इसके लिए, हम एक चर का उपयोग करते हैं जहां हम फ़ंक्शन के बारे में जानकारी संग्रहीत करने के लिए कहते हैं। इसकी आवश्यकता के अनुसार एप्लिकेशन इस चर को फ़ंक्शन के बारे में जानकारी के साथ सेट करेगा जिसे कॉल किया जाएगा और उसी चर का उपयोग करके फ़ंक्शन को कॉल करेगा।
जावास्क्रिप्ट में, उदाहरण नीचे है। यहां हम विधि तर्क का उपयोग एक चर के रूप में करते हैं जहां हम फ़ंक्शन के बारे में जानकारी संग्रहीत करते हैं।
function processArray(arr, callback) {
var resultArr = new Array();
for (var i = arr.length-1; i >= 0; i--)
resultArr[i] = callback(arr[i]);
return resultArr;
}
var arr = [1, 2, 3, 4];
var arrReturned = processArray(arr, function(arg) {return arg * -1;});
// arrReturned would be [-1, -2, -3, -4]
function(arg)
) को processArray(arr,callback)
फंक्शन में कहते हैं
मैं इस मृत को सरल रखने की कोशिश करने जा रहा हूं। एक "कॉलबैक" किसी भी फ़ंक्शन को दूसरे फ़ंक्शन द्वारा बुलाया जाता है जो पैरामीटर के रूप में पहला फ़ंक्शन लेता है। बहुत बार, एक "कॉलबैक" एक फ़ंक्शन है जिसे तब होता है जब कुछ होता है। यही कारण है कि कुछ प्रोग्रामर बात में एक "घटना" कहा जा सकता है।
इस परिदृश्य की कल्पना करें: आप कुछ दिनों में एक पैकेज की उम्मीद कर रहे हैं। पैकेज आपके पड़ोसी के लिए एक उपहार है। इसलिए, एक बार जब आप पैकेज प्राप्त करते हैं, तो आप चाहते हैं कि यह पड़ोसियों के लिए लाया जाए। आप शहर से बाहर हैं, और इसलिए आप अपने पति या पत्नी के लिए निर्देश छोड़ते हैं।
आप उन्हें पैकेज प्राप्त करने और पड़ोसियों को लाने के लिए कह सकते हैं। यदि आपका पति एक कंप्यूटर की तरह बेवकूफ था, तो वे दरवाजे पर बैठते थे और तब तक पैकेज का इंतजार करते थे, जब तक वह नहीं आते (कुछ भी नहीं कर रहे ELSE) और फिर एक बार जब वे आए तो वे इसे पड़ोसियों के सामने लाएंगे। लेकिन एक बेहतर तरीका है। अपने जीवनसाथी को बताएं कि ONCE को वे पैकेज प्राप्त करते हैं, उन्हें इसे पड़ोसियों पर लाना चाहिए। फिर, वे जीवन के बारे में जा सकते हैं आम तौर पर UNTIL वे पैकेज प्राप्त करते हैं।
हमारे उदाहरण में, पैकेज की प्राप्ति "घटना" है और इसे पड़ोसियों के लिए लाना "कॉलबैक" है। अपने पति या पत्नी "रन" अपने निर्देशों से अधिक पैकेज लाने के लिए केवल जब पैकेज आता है। काफी बेहतर!
दैनिक जीवन में इस तरह की सोच स्पष्ट है, लेकिन कंप्यूटर में एक ही तरह का सामान्य ज्ञान नहीं है। इस बात पर विचार करें कि प्रोग्रामर सामान्य रूप से फाइल में कैसे लिखते हैं:
fileObject = open(file)
# now that we have WAITED for the file to open, we can write to it
fileObject.write("We are writing to the file.")
# now we can continue doing the other, totally unrelated things our program does
यहां, हम फ़ाइल को खोलने के लिए WAIT करते हैं, इससे पहले कि हम इसे लिखें। यह निष्पादन के प्रवाह को "ब्लॉक" करता है, और हमारे कार्यक्रम को अन्य चीजों में से कोई भी ऐसा नहीं कर सकता है जो इसे करने की आवश्यकता हो सकती है! क्या होगा अगर हम इसके बजाय यह कर सकते हैं:
# we pass writeToFile (A CALLBACK FUNCTION!) to the open function
fileObject = open(file, writeToFile)
# execution continues flowing -- we don't wait for the file to be opened
# ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS!
यह पता चला है कि हम कुछ भाषाओं और रूपरेखाओं के साथ ऐसा करते हैं। यह बहुत अच्छा है! इस तरह की सोच के साथ कुछ वास्तविक अभ्यास प्राप्त करने के लिए Node.js देखें ।
open
काम करता है पर धारणा बनाने के लिए लगता है । यह प्रशंसनीय है जो open
अपने काले जादू को करने के लिए ओएस की प्रतीक्षा करते हुए आंतरिक रूप से ब्लॉक कर सकता है, जिस पर कॉलबैक निष्पादित होता है। ऐसे मामले में परिणाम में कोई अंतर नहीं है।
सादे अंग्रेजी में कॉलबैक की व्याख्या कैसे करें?
सादे अंग्रेजी में, एक कॉलबैक फ़ंक्शन एक कार्यकर्ता की तरह होता है जो एक कार्य पूरा करने के बाद अपने प्रबंधक को "कॉल बैक" करता है ।
वे दूसरे फ़ंक्शन से एक फ़ंक्शन को कॉल करने के फ़ंक्शन से कुछ संदर्भ लेते हुए कैसे भिन्न होते हैं?
यह सच है कि आप किसी फ़ंक्शन को किसी अन्य फ़ंक्शन से कॉल कर रहे हैं, लेकिन कुंजी यह है कि कॉलबैक को ऑब्जेक्ट की तरह माना जाता है, इसलिए आप सिस्टम की स्थिति के आधार पर कॉल को बदल सकते हैं (जैसे कि स्ट्रेटेजी डिज़ाइन पैटर्न)।
एक नौसिखिया प्रोग्रामर को उनकी शक्ति कैसे समझाई जा सकती है?
कॉलबैक की शक्ति आसानी से AJAX शैली की वेबसाइटों में देखी जा सकती है, जिन्हें सर्वर से डेटा खींचने की आवश्यकता होती है। नया डेटा डाउनलोड करने में कुछ समय लग सकता है। कॉलबैक के बिना, आपका संपूर्ण उपयोगकर्ता इंटरफ़ेस नया डेटा डाउनलोड करते समय "फ्रीज" करेगा, या आपको इसके केवल भाग के बजाय पूरे पृष्ठ को रीफ़्रेश करना होगा। कॉलबैक के साथ, आप "अब लोड हो रहा है" छवि सम्मिलित कर सकते हैं और लोड होने के बाद इसे नए डेटा से बदल सकते हैं।
function grabAndFreeze() {
showNowLoading(true);
var jsondata = getData('http://yourserver.com/data/messages.json');
/* User Interface 'freezes' while getting data */
processData(jsondata);
showNowLoading(false);
do_other_stuff(); // not called until data fully downloaded
}
function processData(jsondata) { // do something with the data
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
यहाँ एक कॉलबैक के साथ एक उदाहरण है, jQuery के getJSON का उपयोग करते हुए :
function processDataCB(jsondata) { // callback: update UI with results
showNowLoading(false);
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
function grabAndGo() { // and don't freeze
showNowLoading(true);
$('#results_messages').html(now_loading_image);
$.getJSON("http://yourserver.com/data/messages.json", processDataCB);
/* Call processDataCB when data is downloaded, no frozen User Interface! */
do_other_stuff(); // called immediately
}
अक्सर उपयोग करने के लिए कॉलबैक जरूरतों state
बुला समारोह से एक का उपयोग कर closure
, जो है जैसे कार्यकर्ता से जानकारी प्राप्त करने की आवश्यकता होगी, प्रबंधक से पहले वह अपने को पूरा कर सकते टास्क । इसे बनाने के लिए closure
, आप फ़ंक्शन को इनलाइन कर सकते हैं ताकि यह कॉलिंग के संदर्भ में डेटा को देखे:
/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) {
if (null == dtable) { dtable = "messages"; }
var uiElem = "_" + dtable;
showNowLoading(true, dtable);
$('#results' + uiElem).html(now_loading_image);
$.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
// Using a closure: can "see" dtable argument and uiElem variables above.
var count = jsondata.results ? jsondata.results.length : 0,
counterMsg = ['Fetched', count, 'new', dtable].join(' '),
// no new chatters/messages/etc
defaultResultsMsg = ['(no new ', dtable, ')'].join('');
showNowLoading(false, dtable);
$('#counter' + uiElem).text(counterMsg);
$('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
});
/* User Interface calls cb when data is downloaded */
do_other_stuff(); // called immediately
}
// update results_chatters when chatters.json data is downloaded:
grab("chatters");
// update results_messages when messages.json data is downloaded
grab("messages");
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback);
अंत में, यहाँ की एक परिभाषा है closure
से डगलस Crockford :
कार्यों को अन्य कार्यों के अंदर परिभाषित किया जा सकता है। आंतरिक फ़ंक्शन में बाहरी फ़ंक्शन के vars और मापदंडों तक पहुंच है। यदि किसी आंतरिक फ़ंक्शन का संदर्भ जीवित रहता है (उदाहरण के लिए, कॉलबैक फ़ंक्शन के रूप में), तो बाहरी फ़ंक्शन के संस्करण भी जीवित रहते हैं।
यह सभी देखें:
मैं बहुत सारे बुद्धिमान लोगों को यह देखकर हक्का-बक्का रह गया कि वास्तविकता को तनाव में डालने में विफल रहा है कि "कॉलबैक" शब्द का उपयोग दो असंगत तरीकों से किया गया है।
दोनों तरीकों में मौजूदा फ़ंक्शन के लिए अतिरिक्त कार्यक्षमता (फ़ंक्शन परिभाषा, अनाम या नामांकित) पास करके फ़ंक्शन का अनुकूलन शामिल है। अर्थात।
customizableFunc(customFunctionality)
यदि कस्टम कार्यक्षमता बस कोड ब्लॉक में प्लग की गई है, तो आपने फ़ंक्शन को अनुकूलित किया है, जैसे।
customizableFucn(customFunctionality) {
var data = doSomthing();
customFunctionality(data);
...
}
हालांकि इस तरह की इंजेक्शन की कार्यक्षमता को अक्सर "कॉलबैक" कहा जाता है, इसके बारे में कुछ भी आकस्मिक नहीं है। एक बहुत स्पष्ट उदाहरण एक पूर्व विधि है जिसमें एक कस्टम फ़ंक्शन को सरणी को संशोधित करने के लिए सरणी में प्रत्येक तत्व पर लागू किए जाने वाले तर्क के रूप में आपूर्ति की जाती है।
लेकिन यह एसिंक्रोनस प्रोग्रामिंग के लिए "कॉलबैक" फ़ंक्शंस के उपयोग से मौलिक रूप से अलग है , जैसा कि AJAX या node.js में या बस उपयोगकर्ता इंटरैक्शन इवेंट (जैसे माउस क्लिक) को कार्यक्षमता प्रदान करने में है। इस मामले में, संपूर्ण विचार कस्टम कार्यक्षमता को निष्पादित करने से पहले एक आकस्मिक घटना होने की प्रतीक्षा करना है। उपयोगकर्ता इंटरैक्शन के मामले में यह स्पष्ट है, लेकिन i / o (इनपुट / आउटपुट) प्रक्रियाओं में भी महत्वपूर्ण है जो डिस्क से फ़ाइलों को पढ़ने की तरह, समय ले सकता है। यह वह जगह है जहां शब्द "कॉलबैक" सबसे स्पष्ट अर्थ बनाता है। एक बार i / o प्रक्रिया शुरू हो जाती है (जैसे डिस्क से पढ़ने के लिए फ़ाइल माँगना या किसी HTTP अनुरोध से डेटा वापस करने के लिए सर्वर) अतुल्यकालिककार्यक्रम समाप्त होने के लिए इसके आसपास प्रतीक्षा नहीं करता है। आगे जो भी कार्य निर्धारित किए गए हैं, वे आगे बढ़ सकते हैं, और केवल कस्टम कार्यक्षमता के साथ प्रतिक्रिया दें क्योंकि यह सूचित किया गया है कि रीड फ़ाइल या http अनुरोध पूरा हो गया है (या यह विफल रहा है) और डेटा कस्टम कार्यक्षमता के लिए उपलब्ध है। यह फोन पर एक व्यवसाय को कॉल करने और अपना "कॉलबैक" नंबर छोड़ने जैसा है, इसलिए वे आपको कॉल कर सकते हैं जब कोई आपके पास वापस आने के लिए उपलब्ध हो। वह लाइन पर लटकने से बेहतर है कि कौन जानता है कि कब तक और अन्य मामलों में भाग लेने में सक्षम नहीं है।
अतुल्यकालिक उपयोग में वांछित घटना के लिए सुनने के कुछ साधन शामिल हैं (जैसे, i / o प्रक्रिया का पूरा होना) ताकि, जब यह घटित हो (और केवल जब यह होता है) तो कस्टम "कॉलबैक" कार्यक्षमता निष्पादित होती है। स्पष्ट AJAX उदाहरण में, जब डेटा वास्तव में सर्वर से आता है, तो "डेटाबैक" फ़ंक्शन को उस डेटा का उपयोग डोम को संशोधित करने के लिए शुरू किया जाता है और इसलिए ब्राउज़र विंडो को उस सीमा तक फिर से लॉन्च किया जाता है।
संक्षेप में दुहराना। कुछ लोग किसी भी प्रकार की कस्टम कार्यक्षमता को संदर्भित करने के लिए "कॉलबैक" शब्द का उपयोग करते हैं जो एक तर्क के रूप में मौजूदा फ़ंक्शन में इंजेक्ट किया जा सकता है। लेकिन, कम से कम मेरे लिए, शब्द का सबसे उपयुक्त उपयोग वह है जहां इंजेक्शन "कॉलबैक" फ़ंक्शन का उपयोग अतुल्यकालिक रूप से किया जाता है - केवल एक घटना की घटना पर निष्पादित होने के लिए जिसे इसे अधिसूचित किए जाने की प्रतीक्षा है।
Array.prototype.forEach()
और फ़ंक्शन एक arg के रूप में पारित किया गया है setTimeout()
, और वे अलग-अलग रंगों के घोड़े हैं जहाँ तक आप अपने कार्यक्रम के बारे में कारण ।
गैर-प्रोग्रामर शब्दों में, एक कॉलबैक एक प्रोग्राम में एक भरने में खाली है।
कई कागज रूपों पर एक सामान्य वस्तु "आपातकाल के मामले में कॉल करने के लिए व्यक्ति" है। वहां एक खाली लाइन है। आप किसी का नाम और फोन नंबर लिखें। यदि कोई आपात स्थिति होती है, तो उस व्यक्ति को बुलाया जाता है।
यह कुंजी है। आप फ़ॉर्म (कोड, आमतौर पर किसी और का) को नहीं बदलते हैं। हालाँकि आप गुम जानकारी ( आपके नंबर) को भर सकते हैं ।
उदाहरण 1:
कॉलबैक का उपयोग अनुकूलित तरीकों के रूप में किया जाता है, संभवतः प्रोग्राम के व्यवहार को जोड़ने / बदलने के लिए। उदाहरण के लिए, एक फ़ंक्शन करने वाले कुछ C कोड लें, लेकिन आउटपुट प्रिंट करना नहीं जानता। यह सब कर सकते हैं एक स्ट्रिंग बनाने के लिए है। जब यह पता लगाने की कोशिश करता है कि स्ट्रिंग के साथ क्या करना है, तो यह एक रिक्त रेखा को देखता है। लेकिन, प्रोग्रामर ने आपको अपना कॉलबैक लिखने के लिए ब्लैंक दिया!
इस उदाहरण में, आप कागज़ की शीट पर रिक्त स्थान को भरने के लिए एक पेंसिल का उपयोग नहीं करते हैं, आप फ़ंक्शन का उपयोग करते हैं set_print_callback(the_callback)
।
set_print_callback
पेंसिल है,the_callback
आपकी जानकारी जो आप भर रहे हैं।अब आप इस खाली लाइन को प्रोग्राम में भर देंगे। जब भी आउटपुट प्रिंट करने की आवश्यकता होती है, तो वह उस ब्लैंक लाइन को देखेगा, और वहां दिए गए निर्देशों का पालन करेगा (यानी आपके द्वारा डाले गए फ़ंक्शन को कॉल करें।) व्यावहारिक रूप से, यह स्क्रीन पर प्रिंट करने की संभावना, लॉग फ़ाइल में, प्रिंटर की अनुमति देता है, एक नेटवर्क कनेक्शन, या उसके किसी भी संयोजन पर। आप जो करना चाहते हैं, उसके साथ आपने रिक्त स्थान को भरा है।
उदाहरण 2:
जब आपको बताया जाता है कि आपको एक आपातकालीन नंबर पर कॉल करने की आवश्यकता है, तो आप जाते हैं और पढ़ते हैं कि पेपर फॉर्म पर क्या लिखा है, और फिर आपके द्वारा पढ़े गए नंबर पर कॉल करें। अगर वह लाइन खाली है तो कुछ भी नहीं किया जाएगा।
गुई प्रोग्रामिंग उसी तरह काम करती है। जब एक बटन पर क्लिक किया जाता है, तो प्रोग्राम को यह पता लगाना होगा कि आगे क्या करना है। यह जाता है और कॉलबैक की तलाश करता है। यह कॉलबैक एक रिक्त लेबल में होता है "यहाँ आप क्या करते हैं जब Button1 क्लिक किया जाता है"
जब आप इसे (जैसे button1_clicked
) पूछेंगे तो अधिकांश आईडीई स्वचालित रूप से आपके लिए रिक्त स्थान भर देंगे (मूल विधि लिखें )। हालाँकि उस रिक्त में कोई भी विधि हो सकती है जिसे आप अच्छी तरह से समझ सकें । आप विधि को कॉल कर सकते हैं run_computations
या butter_the_biscuits
जब तक आप उस कॉलबैक का नाम उचित रिक्त में रखते हैं। आप आपातकालीन नंबर खाली में "555-555-1212" डाल सकते हैं। यह बहुत मतलब नहीं है, लेकिन यह अनुमेय है।
अंतिम नोट: वह रिक्त रेखा जो आप कॉलबैक से भर रहे हैं? इसे मिटाया जा सकता है और वसीयत में दोबारा लिखा जा सकता है। (आपको एक और सवाल करना चाहिए या नहीं, लेकिन यह उनकी शक्ति का एक हिस्सा है)
हमेशा एक उदाहरण के साथ शुरू करने के लिए बेहतर है :)।
मान लेते हैं कि आपके पास दो मॉड्यूल A और B हैं।
आप चाहते हैं कि मॉड्यूल A को सूचित किया जाए जब मॉड्यूल बी में कुछ घटना / स्थिति होती है। हालांकि, मॉड्यूल B को आपके मॉड्यूल ए के बारे में कोई पता नहीं है। यह सब जानता है कि एक फ़ंक्शन पॉइंटर के माध्यम से एक विशेष फ़ंक्शन (मॉड्यूल ए) का पता है मॉड्यूल ए द्वारा इसे प्रदान किया गया।
तो सभी बी को अब करना होगा, मॉड्यूल ए में "कॉलबैक" है जब फ़ंक्शन पॉइंटर का उपयोग करके एक विशेष घटना / स्थिति होती है। A कॉलबैक फ़ंक्शन के अंदर आगे की प्रक्रिया कर सकता है।
*) यहां एक स्पष्ट लाभ यह है कि आप मॉड्यूल ए के बारे में सब कुछ अमूर्त कर रहे हैं। मॉड्यूल बी से मॉड्यूल बी को परवाह नहीं है कि मॉड्यूल क्या है / ए क्या है।
कल्पना कीजिए कि आपको एक ऐसा फंक्शन चाहिए जो 10 स्क्वेयर देता है ताकि आप एक फंक्शन लिखें:
function tenSquared() {return 10*10;}
बाद में आपको 9 चौकों की जरूरत है ताकि आप एक और फ़ंक्शन लिखें:
function nineSquared() {return 9*9;}
आखिरकार आप इन सभी को एक सामान्य कार्य से बदल देंगे:
function square(x) {return x*x;}
ठीक यही सोच कॉलबैक के लिए भी लागू होती है। आपके पास एक फ़ंक्शन है जो कुछ करता है और जब कॉल किया जाता है doA:
function computeA(){
...
doA(result);
}
बाद में आप संपूर्ण फ़ंक्शन को डुप्लिकेट करने के बजाय doB को कॉल करने के लिए सटीक फ़ंक्शन चाहते हैं:
function computeB(){
...
doB(result);
}
या आप एक चर के रूप में कॉलबैक फ़ंक्शन पास कर सकते हैं और केवल एक बार फ़ंक्शन करना होगा:
function compute(callback){
...
callback(result);
}
फिर आपको सिर्फ कंप्यूट (doA) और कंप्यूट (doB) को कॉल करना होगा।
कोड को सरल बनाने से परे, यह अतुल्यकालिक कोड आपको यह बताता है कि आपने अपने मनमाने फ़ंक्शन को पूरा करने पर कॉल किया है, जब आप किसी को फोन पर कॉल करते हैं और कॉलबैक नंबर छोड़ते हैं।
जॉनी प्रोग्रामर को एक स्टेपलर की आवश्यकता होती है, इसलिए वह कार्यालय आपूर्ति विभाग में जाता है और एक के लिए पूछता है, अनुरोध फॉर्म भरने के बाद वह या तो वहां खड़ा हो सकता है और क्लर्क के लिए स्टेपलर के लिए गोदाम के चारों ओर देखने का इंतजार कर सकता है (एक अवरुद्ध कॉल की तरह) ) या जाओ इस बीच कुछ और करो।
चूँकि आमतौर पर इसमें समय लगता है, जॉनी अनुरोध फॉर्म के साथ एक नोट डालता है, जिसमें उनसे पूछा जाता है कि स्टेपलर पिकअप के लिए तैयार है या नहीं, तो इस बीच वह कुछ और कर सकता है जैसे कि उसकी मेज पर नप जाना।
आप बीमार महसूस करते हैं इसलिए आप डॉक्टर के पास जाते हैं। वह आपकी जांच करता है और निर्धारित करता है कि आपको कुछ दवा की आवश्यकता है। वह कुछ मेड्स निर्धारित करता है और आपके स्थानीय फार्मेसी में पर्चे को कॉल करता है। तुम घर जाओ। बाद में आपकी फार्मेसी आपको बताती है कि आपका नुस्खा तैयार है। तुम जाओ और इसे उठाओ।
समझाने के लिए दो बिंदु हैं, एक यह है कि एक कॉलबैक कैसे काम करता है (एक फ़ंक्शन के चारों ओर गुजरता है जिसे इसके संदर्भ के किसी भी ज्ञान के बिना बुलाया जा सकता है), दूसरा वह जो इसके लिए उपयोग किया जाता है (घटनाओं को अतुल्यकालिक रूप से संभालना)।
पार्सल के आने की प्रतीक्षा की उपमा जो अन्य उत्तरों द्वारा उपयोग की गई है, दोनों को समझाने के लिए अच्छा है। एक कंप्यूटर प्रोग्राम में, आप कंप्यूटर को पार्सल की उम्मीद करने के लिए कहेंगे। आमतौर पर, यह अब वहां बैठेगा और पार्सल आने तक प्रतीक्षा (और कुछ नहीं) करेगा, संभवतः अनिश्चित काल के लिए यदि यह कभी नहीं आता है। इंसानों के लिए, यह मूर्खतापूर्ण लगता है, लेकिन आगे के उपायों के बिना, यह पूरी तरह से कंप्यूटर के लिए स्वाभाविक है।
अब कॉलबैक आपके सामने वाले दरवाजे की घंटी होगी। आप पार्सल सेवा प्रदान करते हैं, जिससे आपको पता चल जाएगा कि आपके पास पार्सल के आगमन की सूचना के बिना, यह पता करने के लिए कि आप घर में कहाँ हैं (भले ही) या घंटी कैसे काम करती है। (उदाहरण के लिए, कुछ "घंटियाँ" वास्तव में एक फोन कॉल भेजती हैं।) क्योंकि आपने एक "कॉलबैक फ़ंक्शन" प्रदान किया है, जिसे किसी भी समय "कॉल" किया जा सकता है, संदर्भ से बाहर, आप अब सामने वाले पोर्च पर बैठना बंद कर सकते हैं और "हैंडल" कर सकते हैं। जब भी समय हो "घटना (पार्सल आगमन का)।
कल्पना कीजिए कि एक दोस्त आपके घर से जा रहा है, और आप उसे बताएं "जब आप घर पहुंचें तो मुझे फोन करें ताकि मुझे पता हो कि आप सुरक्षित रूप से पहुंचे"; वह (वस्तुतः) एक कॉल बैक है । भाषा की परवाह किए बिना कॉलबैक फ़ंक्शन क्या है। जब आप कुछ कार्य पूरा कर लेते हैं, तो आप नियंत्रण वापस करने के लिए कुछ प्रक्रिया चाहते हैं, इसलिए आप इसे वापस कॉल करने के लिए उपयोग करने के लिए एक फ़ंक्शन देते हैं।
उदाहरण के लिए, पायथन में,
grabDBValue( (lambda x: passValueToGUIWindow(x) ))
grabDBValue
एक डेटाबेस से केवल एक मूल्य हड़पने के लिए लिखा जा सकता है और फिर आपको यह निर्दिष्ट करने देता है कि वास्तव में मूल्य के साथ क्या करना है, इसलिए यह एक फ़ंक्शन को स्वीकार करता है। आपको नहीं पता कि कब या क्या grabDBValue
वापस आएगा, लेकिन अगर / जब यह करता है, तो आप जानते हैं कि आप क्या करना चाहते हैं। यहां, मैं एक अनाम फ़ंक्शन (या लैम्ब्डा ) में गुजरता हूं जो मान को GUI विंडो पर भेजता है। मैं यह करके कार्यक्रम के व्यवहार को आसानी से बदल सकता था:
grabDBValue( (lambda x: passToLogger(x) ))
कॉलबैक उन भाषाओं में अच्छी तरह से काम करता है जहां फ़ंक्शंस प्रथम श्रेणी के मान होते हैं, जैसे सामान्य पूर्णांक, वर्ण स्ट्रिंग्स, बूलियन, आदि। C में, आप एक पॉइंटर को इसके चारों ओर से गुजरते हुए एक फ़ंक्शन को "पास" कर सकते हैं और कॉलर इसका उपयोग कर सकता है; जावा में, कॉलर एक निश्चित विधि नाम के साथ एक निश्चित प्रकार के स्थिर वर्ग के लिए पूछेगा क्योंकि कक्षाओं के बाहर कोई फ़ंक्शन ("विधियाँ," वास्तव में) नहीं हैं; और अधिकांश अन्य गतिशील भाषाओं में आप केवल सरल वाक्यविन्यास के साथ एक फ़ंक्शन पास कर सकते हैं।
लेक्सिकल स्कूपिंग (जैसे स्कीम या पर्ल) वाली भाषाओं में आप इस तरह से एक ट्रिक खींच सकते हैं:
my $var = 2;
my $val = someCallerBackFunction(sub callback { return $var * 3; });
# Perlistas note: I know the sub doesn't need a name, this is for illustration
$val
इस स्थिति में यह होगा 6
क्योंकि कॉलबैक में लेक्सिकल वातावरण में घोषित चर की पहुंच है जहां इसे परिभाषित किया गया था। लेक्सिकल स्कोप और अनाम कॉलबैक नौसिखिया प्रोग्रामर के लिए आगे के अध्ययन का एक शक्तिशाली संयोजन है।
आपके पास कुछ कोड हैं जिन्हें आप चलाना चाहते हैं। आम तौर पर, जब आप इसे कहते हैं, तो आप इसे ले जाने से पहले समाप्त होने की प्रतीक्षा कर रहे होते हैं (जिससे आपका ऐप ग्रे हो सकता है / कर्सर के लिए कताई समय का उत्पादन कर सकता है)।
एक वैकल्पिक विधि इस कोड को समानांतर में चलाने और अपने स्वयं के काम के साथ ले जाने के लिए है। लेकिन क्या होगा यदि आपके मूल कोड को उसके द्वारा कहे गए कोड से प्रतिक्रिया के आधार पर अलग-अलग चीजें करने की ज़रूरत है? ठीक है, उस स्थिति में आप उस कोड के नाम / स्थान को पास कर सकते हैं जिसे आप चाहते हैं कि जब यह हो जाए तो उसे कॉल करें। यह एक "कॉल बैक" है।
सामान्य कोड: जानकारी के लिए पूछें-> प्रक्रिया की जानकारी-> प्रसंस्करण के परिणामों से निपटें-> अन्य चीजें करना जारी रखें।
कॉलबैक के साथ: जानकारी के लिए पूछें-> प्रक्रिया की जानकारी-> अन्य चीजें करना जारी रखें। और कुछ बाद के बिंदु पर-> प्रसंस्करण के परिणामों से निपटें।
कॉलबैक के बिना न तो अन्य विशेष प्रोग्रामिंग संसाधन (जैसे थ्रेडिंग, और अन्य), एक कार्यक्रम बिल्कुल निर्देशों का एक क्रम है, जो क्रमिक रूप से एक के बाद एक निष्पादित होते हैं , और यहां तक कि कुछ शर्तों द्वारा निर्धारित एक प्रकार के "गतिशील व्यवहार" के साथ, सभी संभव परिदृश्य पहले प्रोग्राम किया जाएगा ।
इसलिए, यदि हमें एक प्रोग्राम में वास्तविक डायनामिक व्यवहार प्रदान करने की आवश्यकता है, तो हम कॉलबैक का उपयोग कर सकते हैं। कॉलबैक के साथ आप मापदंडों द्वारा निर्देश दे सकते हैं, एक प्रोग्राम एक अन्य प्रोग्राम को कॉल कर सकते हैं जो कुछ पहले से परिभाषित पैरामीटर प्रदान कर रहा है और कुछ परिणामों की उम्मीद कर सकता है ( यह अनुबंध या ऑपरेशन हस्ताक्षर है ), इसलिए इन परिणामों का उत्पादन / प्रक्रिया तीसरे पक्ष के कार्यक्रम द्वारा किया जा सकता है जो 'पहले से जाना जाता है।
यह तकनीक प्रोग्राम, फ़ंक्शंस, ऑब्जेक्ट्स और कंप्यूटर द्वारा चलाए गए कोड के अन्य सभी यूनियनों पर लागू होने वाले बहुरूपता की नींव है।
कॉलबैक के उदाहरण के रूप में इस्तेमाल की जाने वाली मानव दुनिया को समझाया जाता है कि जब आप कुछ काम कर रहे होते हैं, तो मान लीजिए कि आप एक चित्रकार हैं ( यहाँ आप मुख्य कार्यक्रम हैं, जो कि पेंट हैं ) और अपने क्लाइंट को कॉल करके कभी-कभी उससे पूछें कि उसे आपकी नौकरी का परिणाम मंजूर है। , इसलिए, यदि चित्र अच्छा है ( आपका ग्राहक तृतीय-पक्ष कार्यक्रम है ) तो वह निर्णय लेता है ।
उपर्युक्त उदाहरण में आप एक चित्रकार हैं और दूसरों को "प्रतिनिधि" बताते हैं कि परिणाम को अनुमोदित करने के लिए काम करते हैं, चित्र पैरामीटर है, और प्रत्येक नए ग्राहक (जिसे "बैक-बैक" फ़ंक्शन ") कहते हैं, जो वह चाहता है, आपके कार्य के परिणाम को बदल देता है। तस्वीर के बारे में ( ग्राहकों द्वारा किए गए निर्णय "कॉलबैक फ़ंक्शन" से लौटे परिणाम हैं )।
मुझे उम्मीद है कि यह स्पष्टीकरण उपयोगी हो सकता है।
आइए दिखाते हैं कि आप मुझे एक लंबे समय तक चलने वाला काम देने वाले थे: पहले पांच अनूठे लोगों के नाम प्राप्त करें जिन्हें आप भरते हैं। यह दिन लग सकता है अगर मैं काफी आबादी वाले क्षेत्र में हूं। जब आप इधर-उधर भाग रहे होते हैं, तो आप वास्तव में अपने हाथों पर बैठने में रुचि नहीं रखते हैं, इसलिए आप कहते हैं, "जब आपको सूची मिल गई है, तो मुझे अपने सेल पर कॉल करें और इसे मेरे पास वापस पढ़ें। यहां नंबर है।"
आपने मुझे कॉलबैक संदर्भ दिया है - एक फ़ंक्शन जिसे मैं आगे की प्रक्रिया को बंद करने के लिए निष्पादित करने वाला हूं।
जावास्क्रिप्ट में यह कुछ इस तरह दिख सकता है:
var lottoNumbers = [];
var callback = function(theNames) {
for (var i=0; i<theNames.length; i++) {
lottoNumbers.push(theNames[i].length);
}
};
db.executeQuery("SELECT name " +
"FROM tblEveryOneInTheWholeWorld " +
"ORDER BY proximity DESC " +
"LIMIT 5", callback);
while (lottoNumbers.length < 5) {
playGolf();
}
playLotto(lottoNumbers);
यह शायद बहुत तरीकों से सुधारा जा सकता है। उदाहरण के लिए, आप दूसरा कॉलबैक प्रदान कर सकते हैं: यदि यह एक घंटे से अधिक समय तक समाप्त होता है, तो लाल फोन पर कॉल करें और उस व्यक्ति को बताएं जो जवाब देता है कि आपने समय समाप्त कर लिया है।
टेलीफोन प्रणाली के संदर्भ में कॉलबैक का सबसे आसानी से वर्णन किया गया है। एक फ़ंक्शन कॉल किसी को टेलीफोन पर कॉल करने के लिए, उसे एक सवाल पूछने, एक उत्तर प्राप्त करने और फांसी देने के अनुरूप है; कॉलबैक जोड़ने से सादृश्य बदल जाता है ताकि उससे सवाल पूछने के बाद, आप उसे अपना नाम और नंबर भी दें ताकि वह आपको उत्तर के साथ वापस बुला सके। - पॉल जकुबिक, "C ++ में कॉलबैक कार्यान्वयन"
कॉलबैक एक फ़ंक्शन है जिसे दूसरे फ़ंक्शन द्वारा कॉल किया जाएगा। यह दूसरा फ़ंक्शन पहले से नहीं जानता है कि यह किस फ़ंक्शन को कॉल करेगा। इसलिए कॉलबैक फ़ंक्शन की पहचान को कहीं पर संग्रहीत किया जाता है, या पैरामीटर के रूप में दूसरे फ़ंक्शन को पास किया जाता है। यह "पहचान", प्रोग्रामिंग भाषा के आधार पर, कॉलबैक, या किसी अन्य प्रकार के पॉइंटर का पता हो सकता है, या यह फ़ंक्शन का नाम हो सकता है। प्रिंसिपल एक ही है, हम कुछ जानकारी को स्टोर करते हैं या पास करते हैं जो स्पष्ट रूप से फ़ंक्शन को पहचानती है।
जब समय आता है, तो दूसरा फ़ंक्शन कॉलबैक कॉल कर सकता है, उस समय परिस्थितियों के आधार पर मापदंडों की आपूर्ति कर सकता है। यह संभव कॉलबैक के सेट से कॉलबैक भी चुन सकता है। प्रोग्रामिंग भाषा को कॉलबैक को कॉल करने के लिए दूसरे फ़ंक्शन को इसकी "पहचान" जानने की अनुमति देने के लिए किसी प्रकार का सिंटैक्स प्रदान करना होगा।
इस तंत्र के कई संभावित उपयोग हैं। कॉलबैक के साथ, किसी फ़ंक्शन के डिज़ाइनर को कॉलबैक प्रदान किए जाने पर उसे कॉल करके अनुकूलित किया जा सकता है। उदाहरण के लिए, एक सॉर्टिंग फ़ंक्शन एक पैरामीटर के रूप में कॉलबैक ले सकता है, और यह कॉलबैक यह निर्णय लेने के लिए दो तत्वों की तुलना करने के लिए एक फ़ंक्शन हो सकता है कि कौन सा पहले आता है।
वैसे, प्रोग्रामिंग भाषा के आधार पर, उपरोक्त चर्चा में "फ़ंक्शन" शब्द को "ब्लॉक," "क्लोजर," "लैम्ब्डा," आदि द्वारा प्रतिस्थापित किया जा सकता है।
आमतौर पर हम कार्यों के लिए चर भेजते हैं। मान लीजिए कि आपके पास कार्य है जहां तर्क के रूप में दिए जाने से पहले चर को संसाधित करने की आवश्यकता है - आप कॉलबैक का उपयोग कर सकते हैं।
function1(var1, var2)
हमेशा की तरह है।
क्या होगा यदि मैं var2
संसाधित होना चाहता हूं और फिर एक तर्क के रूप में भेजा जाता है?
function1(var1, function2(var2))
यह एक प्रकार का कॉलबैक है - जहां function2
कुछ कोड निष्पादित करता है और प्रारंभिक फ़ंक्शन पर एक चर वापस देता है।
एक रूपक व्याख्या:
मेरे पास एक पार्सल है जिसे मैं एक दोस्त को देना चाहता हूं, और मैं यह भी जानना चाहता हूं कि मेरा दोस्त कब प्राप्त करता है।
इसलिए मैं पार्सल को पोस्ट ऑफिस ले जाता हूं और उन्हें इसे डिलीवर करने के लिए कहता हूं। अगर मुझे पता है कि मेरे दोस्त को पार्सल कब मिलेगा, तो मेरे पास दो विकल्प हैं:
(ए) मैं पोस्ट ऑफिस में तब तक इंतजार कर सकता हूं जब तक कि उसकी डिलीवरी नहीं हो जाती।
(b) जब यह डिलीवर होगा तब मुझे एक ईमेल मिलेगा।
विकल्प (बी) एक कॉलबैक के अनुरूप है।
कॉलबैक सिखाने के लिए, आपको पहले पॉइंटर सिखाना होगा। एक बार जब छात्र पॉइंटर के विचार को एक चर में समझ लेते हैं, तो कॉलबैक का विचार आसान हो जाएगा। मान लें कि आप C / C ++ का उपयोग कर रहे हैं, तो इन चरणों का पालन किया जा सकता है।
और भी कई बातें हो सकती हैं। छात्रों को शामिल करें और वे खोज करेंगे। उम्मीद है की यह मदद करेगा।
सादे अंग्रेजी में एक कॉलबैक एक वादा है। जो, जेन, डेविड और सामंथा काम करने के लिए एक कारपूल साझा करते हैं। जो आज चला रहा है। जेन, डेविड और सामंथा के पास कुछ विकल्प हैं:
विकल्प 1: यह एक मतदान उदाहरण की तरह है जहां जेन एक "लूप" चेक में फंस जाएगा यदि जो बाहर है। मतलब समय में जेन कुछ और नहीं कर सकता।
विकल्प 2: यह कॉलबैक उदाहरण है। जब वह बाहर होता है तो जेन अपने दरवाजे की घंटी बजाने के लिए कहता है। वह उसे दरवाजे की घंटी बजाने के लिए "फंक्शन" देती है। जो को यह जानने की जरूरत नहीं है कि दरवाजे की घंटी कैसे काम करती है या यह कहां है, उसे बस उस फ़ंक्शन को कॉल करने की आवश्यकता है यानी जब वहां घंटी बजती है।
कॉलबैक "घटनाओं" द्वारा संचालित होते हैं। इस उदाहरण में "घटना" जो का आगमन है। उदाहरण के लिए अजाक्स में घटनाओं को अतुल्यकालिक अनुरोध की "सफलता" या "विफलता" हो सकती है और प्रत्येक में समान या अलग-अलग कमियां हो सकती हैं।
जावास्क्रिप्ट अनुप्रयोगों और कॉलबैक के संदर्भ में। हमें "क्लोजर" और एप्लिकेशन संदर्भ को भी समझने की आवश्यकता है। क्या "यह" जावास्क्रिप्ट डेवलपर्स को आसानी से भ्रमित कर सकता है। इस उदाहरण में प्रत्येक व्यक्ति के "ring_the_door_bell ()" पद्धति / कॉलबैक में कुछ अन्य तरीके हो सकते हैं जो प्रत्येक व्यक्ति को अपनी सुबह की दिनचर्या के आधार पर करने की आवश्यकता होती है। "टीवी बंद करो()"। हम "इसे" "जेन" ऑब्जेक्ट या "डेविड" ऑब्जेक्ट को संदर्भित करना चाहते हैं ताकि प्रत्येक जो कुछ भी आवश्यक हो उसे सेटअप कर सके जो जो उन्हें लेने से पहले करता है। यह वह जगह है जहां जोबैक के साथ कॉलबैक स्थापित करने के लिए विधि की पैरोडिंग की आवश्यकता होती है ताकि "यह" सही वस्तु को संदर्भित करे।
उम्मीद है की वो मदद करदे!
मुझे लगता है कि यह समझाना आसान काम है।
पहले कॉलबैक में सिर्फ साधारण कार्य होते हैं।
और आगे, यह है कि हम इस फ़ंक्शन को कॉल करते हैं (चलो इसे ए कहते हैं) दूसरे फ़ंक्शन के अंदर से (चलो इसे बी कहते हैं)।
इस बारे में जादू यह है कि मैं तय करता हूं, बी के बाहर से किस फ़ंक्शन को कॉल किया जाना चाहिए ।
जब मैं फ़ंक्शन लिखता हूं तो बीआई को पता नहीं होता है कि किस कॉलबैक फ़ंक्शन को बुलाया जाना चाहिए। जिस समय मैं फंक्शन बीआई कहता हूं, वह इस फ़ंक्शन को फ़ंक्शन ए को कॉल करने के लिए भी कहता है।
कॉलबैक फ़ंक्शन क्या है?
इस पहले प्रश्न का सरल उत्तर यह है कि कॉलबैक फ़ंक्शन एक फ़ंक्शन है जिसे फ़ंक्शन पॉइंटर के माध्यम से कहा जाता है। यदि आप किसी फ़ंक्शन के पॉइंटर (पता) को दूसरे के तर्क के रूप में पास करते हैं, जब उस फ़ंक्शन को कॉल करने के लिए उस पॉइंटर का उपयोग किया जाता है, तो यह कहा जाता है कि कॉल बैक किया गया है।
कॉलबैक फ़ंक्शन का पता लगाना कठिन है, लेकिन कभी-कभी यह बहुत उपयोगी होता है। खासतौर पर जब आप लाइब्रेरी डिजाइन कर रहे हों। कॉलबैक फ़ंक्शन आपके उपयोगकर्ता को आपको एक फ़ंक्शन नाम देने के लिए कहने जैसा है, और आप निश्चित फ़ंक्शन के तहत उस फ़ंक्शन को कॉल करेंगे।
उदाहरण के लिए, आप कॉलबैक टाइमर लिखते हैं। यह आपको अवधि निर्दिष्ट करने की अनुमति देता है और किस फ़ंक्शन को कॉल करना है, और फ़ंक्शन तदनुसार कॉलबैक होगा। "हर 10 सेकंड में 5 बार myfunction () चलाएं"
या आप एक फ़ंक्शन डायरेक्टरी बना सकते हैं, फ़ंक्शन नाम की एक सूची पास कर सकते हैं और लाइब्रेरी को तदनुसार कॉलबैक करने के लिए कह सकते हैं। "कॉलबैक सफलता () यदि सफलता, कॉलबैक विफल () विफल रही है।"
चलो एक साधारण फ़ंक्शन पॉइंटर उदाहरण देखें
void cbfunc()
{
printf("called");
}
int main ()
{
/* function pointer */
void (*callback)(void);
/* point to your callback function */
callback=(void *)cbfunc;
/* perform callback */
callback();
return 0;
}
कॉलबैक फ़ंक्शन के लिए तर्क कैसे पास करें?
कॉलबैक को लागू करने के लिए फ़ंक्शन पॉइंटर को ऑब्ज़र्वर * शून्य में ले जाता है, जो इंगित करता है कि यह संरचना सहित किसी भी प्रकार के चर में ले जा सकता है। इसलिए आप संरचना द्वारा कई तर्कों में पारित कर सकते हैं।
typedef struct myst
{
int a;
char b[10];
}myst;
void cbfunc(myst *mt)
{
fprintf(stdout,"called %d %s.",mt->a,mt->b);
}
int main()
{
/* func pointer */
void (*callback)(void *); //param
myst m;
m.a=10;
strcpy(m.b,"123");
callback = (void*)cbfunc; /* point to callback function */
callback(&m); /* perform callback and pass in the param */
return 0;
}
एक कॉलबैक एक विधि है जिसे किसी शर्त के पूरा होने पर निष्पादित किया जाना है।
एक "वास्तविक दुनिया" उदाहरण एक स्थानीय वीडियो गेम स्टोर है। आप हाफ-लाइफ 3 की प्रतीक्षा कर रहे हैं। हर दिन स्टोर पर जाने के बजाय यह देखने के लिए कि क्या यह उपलब्ध है, आप खेल उपलब्ध होने पर अधिसूचित होने के लिए एक सूची पर अपना ईमेल पंजीकृत करते हैं। ईमेल आपका "कॉलबैक" बन जाता है और मिलने की शर्त खेल की उपलब्धता है।
एक "प्रोग्रामर" उदाहरण एक वेब पेज है जहां आप एक बटन क्लिक करने पर कार्रवाई करना चाहते हैं। आप एक बटन के लिए कॉलबैक विधि पंजीकृत करते हैं और अन्य कार्य करते रहते हैं। जब / यदि उपयोगकर्ता बटन पर चिपक जाता है, तो ब्राउज़र उस घटना के लिए कॉलबैक की सूची को देखेगा और आपकी विधि को कॉल करेगा।
कॉलबैक घटनाओं को अतुल्यकालिक रूप से संभालने का एक तरीका है। आपको कभी पता नहीं चल सकता है कि कॉलबैक कब निष्पादित किया जाएगा, या यदि इसे बिल्कुल निष्पादित किया जाएगा। लाभ यह है कि यह आपके कार्यक्रम और सीपीयू चक्रों को उत्तर की प्रतीक्षा करते हुए अन्य कार्यों को करने के लिए मुक्त करता है।
सादा और सरल: एक कॉलबैक एक फ़ंक्शन है जिसे आप किसी अन्य फ़ंक्शन को देते हैं, ताकि इसे कॉल कर सकें।
आमतौर पर यह कहा जाता है जब कुछ ऑपरेशन पूरा हो जाता है। चूंकि आप दूसरे फ़ंक्शन को देने से पहले कॉलबैक बनाते हैं, इसलिए आप इसे कॉल साइट से संदर्भ जानकारी के साथ प्रारंभ कर सकते हैं। इसीलिए इसे कॉल बैक * बैक * नाम दिया गया है - पहला फ़ंक्शन उस संदर्भ में कॉल बैक करता है, जहाँ से इसे कॉल किया गया था।
“कंप्यूटर प्रोग्रामिंग में, कॉलबैक निष्पादन योग्य कोड, या निष्पादन योग्य कोड का एक टुकड़ा है, जो अन्य कोड के तर्क के रूप में पारित किया जाता है। यह निम्न-स्तरीय सॉफ़्टवेयर परत को उच्च-स्तरीय परत में परिभाषित उप-रेखा (या फ़ंक्शन) को कॉल करने की अनुमति देता है। " - विकिपीडिया
फ़ंक्शन सूचक का उपयोग करके C में कॉलबैक
C में, फ़ंक्शन पॉइंटर का उपयोग करके कॉलबैक लागू किया जाता है। फ़ंक्शन पॉइंटर - जैसा कि नाम से पता चलता है, एक फ़ंक्शन के लिए एक संकेतक है।
उदाहरण के लिए, int (* ptrFunc) ();
यहां, ptrFunc एक फ़ंक्शन का एक संकेतक है जो कोई तर्क नहीं लेता है और पूर्णांक देता है। कोष्ठक में रखना मत भूलना, अन्यथा संकलक मान लेंगे कि ptrFunc एक सामान्य फ़ंक्शन नाम है, जो कुछ भी नहीं लेता है और एक पूर्णांक के लिए एक संकेतक लौटाता है।
फ़ंक्शन पॉइंटर को प्रदर्शित करने के लिए यहां कुछ कोड दिए गए हैं।
#include<stdio.h>
int func(int, int);
int main(void)
{
int result1,result2;
/* declaring a pointer to a function which takes
two int arguments and returns an integer as result */
int (*ptrFunc)(int,int);
/* assigning ptrFunc to func's address */
ptrFunc=func;
/* calling func() through explicit dereference */
result1 = (*ptrFunc)(10,20);
/* calling func() through implicit dereference */
result2 = ptrFunc(10,20);
printf("result1 = %d result2 = %d\n",result1,result2);
return 0;
}
int func(int x, int y)
{
return x+y;
}
अब हम फ़ंक्शन पॉइंटर का उपयोग करके C में कॉलबैक की अवधारणा को समझने का प्रयास करते हैं।
पूर्ण कार्यक्रम में तीन फाइलें हैं: callback.c, reg_callback.h और reg_callback.c।
/* callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* callback function definition goes here */
void my_callback(void)
{
printf("inside my_callback\n");
}
int main(void)
{
/* initialize function pointer to
my_callback */
callback ptr_my_callback=my_callback;
printf("This is a program demonstrating function callback\n");
/* register our callback function */
register_callback(ptr_my_callback);
printf("back inside main program\n");
return 0;
}
/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);
/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
printf("inside register_callback\n");
/* calling our callback function my_callback */
(*ptr_reg_callback)();
}
यदि हम इस प्रोग्राम को चलाते हैं, तो आउटपुट होगा
यह मुख्य कार्यक्रम के अंदर my_callback के अंदर register_callback के अंदर फ़ंक्शन कॉलबैक प्रदर्शित करने वाला एक प्रोग्राम है
उच्च परत फ़ंक्शन सामान्य कॉल के रूप में एक निचली परत फ़ंक्शन को कॉल करता है और कॉलबैक तंत्र किसी कॉलबैक फ़ंक्शन के लिए पॉइंटर के माध्यम से उच्च परत फ़ंक्शन को कॉल करने की अनुमति देता है।
इंटरफ़ेस का उपयोग करके जावा में कॉलबैक
जावा में फंक्शन पॉइंटर की अवधारणा नहीं है। यह अपने इंटरफेस तंत्र के माध्यम से कॉलबैक तंत्र को लागू करता है। यहां फ़ंक्शन पॉइंटर के बजाय, हम एक इंटरफ़ेस की घोषणा करते हैं जिसमें एक विधि होती है जिसे कॉल किया जाता है जब कैली अपने कार्य को पूरा करता है।
मुझे एक उदाहरण के माध्यम से इसे प्रदर्शित करने दें:
कॉलबैक इंटरफ़ेस
public interface Callback
{
public void notify(Result result);
}
कॉलर या उच्च स्तर की कक्षा
public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee
//Other functionality
//Call the Asynctask
ce.doAsynctask();
public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}
कैली या निचली परत का कार्य
public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}
doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}
EventListener पैटर्न का उपयोग कर कॉलबैक
इस पैटर्न का उपयोग पर्यवेक्षकों / श्रोताओं की 0 से n संख्याओं को सूचित करने के लिए किया जाता है जो एक विशेष कार्य समाप्त हो गया है
कॉलबैक तंत्र और EventListener / ऑब्जर्वर तंत्र के बीच का अंतर यह है कि कॉलबैक में, कॉलली एकल कॉलर को सूचित करता है, जबकि Eventlisener / ऑब्जर्वर में, कैलि उस व्यक्ति को सूचित कर सकता है जो उस ईवेंट में रुचि रखता है (अधिसूचना कुछ अन्य भागों में जा सकती है) अनुप्रयोग जिसने कार्य को ट्रिगर नहीं किया है)
इसे एक उदाहरण के माध्यम से समझाता हूं।
इवेंट इंटरफ़ेस
public interface Events {
public void clickEvent();
public void longClickEvent();
}
वर्ग विजेट
package com.som_itsolutions.training.java.exampleeventlistener;
import java.util.ArrayList;
import java.util.Iterator;
public class Widget implements Events{
ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>();
ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();
@Override
public void clickEvent() {
// TODO Auto-generated method stub
Iterator<OnClickEventListener> it = mClickEventListener.iterator();
while(it.hasNext()){
OnClickEventListener li = it.next();
li.onClick(this);
}
}
@Override
public void longClickEvent() {
// TODO Auto-generated method stub
Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
while(it.hasNext()){
OnLongClickEventListener li = it.next();
li.onLongClick(this);
}
}
public interface OnClickEventListener
{
public void onClick (Widget source);
}
public interface OnLongClickEventListener
{
public void onLongClick (Widget source);
}
public void setOnClickEventListner(OnClickEventListener li){
mClickEventListener.add(li);
}
public void setOnLongClickEventListner(OnLongClickEventListener li){
mLongClickEventListener.add(li);
}
}
कक्षा बटन
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
कक्षा चेकबॉक्स
public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}
गतिविधि वर्ग
पैकेज com.som_itsolutions.training.java.exampleeventlistener;
public class Activity implements Widget.OnClickEventListener
{
public Button mButton;
public CheckBox mCheckBox;
private static Activity mActivityHandler;
public static Activity getActivityHandle(){
return mActivityHandler;
}
public Activity ()
{
mActivityHandler = this;
mButton = new Button();
mButton.setOnClickEventListner(this);
mCheckBox = new CheckBox();
mCheckBox.setOnClickEventListner(this);
}
public void onClick (Widget source)
{
if(source == mButton){
mButton.setButtonText("Thank you for clicking me...");
System.out.println(((Button) mButton).getButtonText());
}
if(source == mCheckBox){
if(mCheckBox.isChecked()==false){
mCheckBox.setCheck(true);
System.out.println("The checkbox is checked...");
}
else{
mCheckBox.setCheck(false);
System.out.println("The checkbox is not checked...");
}
}
}
public void doSomeWork(Widget source){
source.clickEvent();
}
}
अन्य वर्ग
public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}
मुख्य वर्ग
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}
जैसा कि आप उपरोक्त कोड से देख सकते हैं, कि हमारे पास एक इंटरफ़ेस है, जिसे इवेंट कहा जाता है, जो मूल रूप से उन सभी घटनाओं को सूचीबद्ध करता है जो हमारे एप्लिकेशन के लिए हो सकती हैं। विजेट वर्ग बटन, चेकबॉक्स जैसे सभी UI घटकों के लिए आधार वर्ग है। ये यूआई घटक ऑब्जेक्ट हैं जो वास्तव में फ्रेमवर्क कोड से घटनाओं को प्राप्त करते हैं। विजेट वर्ग ईवेंट इंटरफ़ेस को लागू करता है और इसमें दो नेस्टेड इंटरफेस भी होते हैं जिनका नाम OnClickEventListener और OnLongClickEventListener है
ये दो इंटरफेस बटन या चेकबॉक्स जैसे विजेट व्युत्पन्न यूआई घटकों पर होने वाली घटनाओं को सुनने के लिए जिम्मेदार हैं। इसलिए यदि हम इस उदाहरण की तुलना जावा इंटरफेस का उपयोग करके पहले के कॉलबैक उदाहरण से करते हैं, तो ये दो इंटरफेस कॉलबैक इंटरफेस के रूप में काम करते हैं। तो उच्च स्तर का कोड (यहां गतिविधि) इन दो इंटरफेस को लागू करता है। और जब भी कोई घटना विजेट में घटित होती है, तो उच्च स्तरीय कोड (या उच्च स्तर कोड में लागू इन इंटरफेस की विधि, जो यहां गतिविधि है) को कहा जाएगा।
अब मुझे कॉलबैक और इवेंटलिस्टर पैटर्न के बीच बुनियादी अंतर पर चर्चा करने दें। जैसा कि हमने उल्लेख किया है कि कॉलबैक का उपयोग करते हुए, कैलली केवल एक ही कॉलर को सूचित कर सकता है। लेकिन EventListener पैटर्न के मामले में, एप्लिकेशन का कोई अन्य भाग या वर्ग बटन या चेकबॉक्स पर होने वाली घटनाओं के लिए पंजीकरण कर सकता है। इस तरह के वर्ग का उदाहरण अन्य क्लैक्सेस है। यदि आप OtherClass का कोड देखते हैं, तो आप पाएंगे कि इसने खुद को ClickEvent में एक श्रोता के रूप में पंजीकृत किया है जो गतिविधि में परिभाषित बटन में हो सकता है। दिलचस्प हिस्सा यह है कि, गतिविधि (कॉलर) के अलावा, यह अन्यक्लास को भी सूचित किया जाएगा जब भी बटन पर क्लिक करने की घटना होती है।
कॉलबैक आपको किसी अन्य समय में निष्पादित किए जाने वाले कोड के किसी अन्य ब्लॉक में अपना कोड डालने की अनुमति देता है, जो आपकी आवश्यकताओं के अनुरूप कोड के उस अन्य ब्लॉक के व्यवहार को संशोधित या जोड़ता है। अधिक लचीले कोड रखने में सक्षम होने के दौरान आप लचीलापन और अनुकूलन क्षमता प्राप्त करते हैं।
कम हार्डकोड = आसान बनाए रखने और बदलने के लिए = कम समय = अधिक व्यावसायिक मूल्य = अजीबता।
उदाहरण के लिए, जावास्क्रिप्ट में, Underscore.js का उपयोग करके, आप इस तरह से एक सरणी में सभी तत्वों को पा सकते हैं:
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
उदाहरण के अंडरस्कोर .js के सौजन्य से: http://documentcloud.github.com/underscore/#filter
[संपादित करें] जब हमारे पास दो फ़ंक्शन हैं functionA और functionB , अगर functionA functionB पर निर्भर करता है ।
फिर हम कहते हैं functionB एक के रूप में कॉलबैक फ़ंक्शन .इस व्यापक रूप से वसंत ढांचे में प्रयोग किया जाता है।
एक सहकर्मी को एक कार्य देने के तरीके के बारे में सोचें। एक साधारण कार्य निम्नलिखित हो सकता है:
Solve these equations:
x + 2 = y
2 * x = 3 * y
आपका सहकर्मी परिश्रम से गणित करता है और आपको निम्नलिखित परिणाम देता है:
x = -6
y = -4
लेकिन आपके सहकर्मी को एक समस्या है, वह हमेशा नोटेशन को नहीं समझता है, जैसे कि ^
, लेकिन वह उन्हें अपने विवरण से समझता है। इस तरह के रूप में exponent
। हर बार वह इनमें से किसी एक को ढूंढता है जो आपको वापस मिलता है:
I don't understand "^"
इसके लिए आपको अपने पूरे निर्देश को फिर से लिखने की आवश्यकता है, यह समझाने के बाद कि आपके सहकर्मी के चरित्र का क्या मतलब है, और वह हमेशा सवालों के बीच याद नहीं करता है। और उसे आपके सुझावों को याद रखने में कठिनाई होती है, जैसे कि मुझसे पूछें। वह हमेशा आपके लिखित निर्देशों का सबसे अच्छा अनुसरण करता है।
आप एक समाधान के बारे में सोचते हैं, आप बस अपने सभी निर्देशों में निम्नलिखित जोड़ते हैं:
If you have any questions about symbols, call me at extension 1234 and I will tell you its name.
अब जब भी उसे कोई समस्या होती है तो वह आपको फोन करता है और आपसे बुरा जवाब देने और प्रक्रिया को फिर से शुरू करने के बजाय पूछता है।
वेबपृष्ठ डाउनलोड करने के संदर्भ में यह इस प्रकार है:
आपका कार्यक्रम एक सेलफोन पर चलता है और वेबपेज http://www.google.com से अनुरोध कर रहा है । यदि आप अपने प्रोग्राम को समकालिक रूप से लिखते हैं, तो डेटा डाउनलोड करने के लिए आप जो फ़ंक्शन लिखते हैं, वह सभी डेटा डाउनलोड होने तक लगातार चलता रहेगा। इसका मतलब है कि आपका UI रीफ्रेश नहीं होगा और मूल रूप से जमे हुए दिखाई देगा। यदि आप कॉलबैक का उपयोग करके अपना प्रोग्राम लिखते हैं, तो आप डेटा का अनुरोध करते हैं और कहते हैं "जब आप समाप्त कर लें तो इस फ़ंक्शन को निष्पादित करें।" यह यूआई को फ़ाइल डाउनलोड करते समय अभी भी उपयोगकर्ता इंटरैक्शन की अनुमति देता है। एक बार वेबपेज डाउनलोड हो जाने के बाद, आपका परिणाम फ़ंक्शन (कॉलबैक) कहलाता है और आप डेटा को संभाल सकते हैं।
मूल रूप से, यह आपको परिणाम के लिए प्रतीक्षा करते समय कुछ अनुरोध करने और निष्पादित करने की अनुमति देता है। एक बार कॉलबैक फ़ंक्शन के माध्यम से परिणाम आपके पास वापस आ जाता है, तो आप उस ऑपरेशन को चुन सकते हैं जहां इसे छोड़ा गया था।