खोज…
सरल कॉलबैक उपयोग उदाहरण
कॉलबैक अपने कोड को बदले बिना किसी फ़ंक्शन (या विधि) की कार्यक्षमता का विस्तार करने का एक तरीका प्रदान करता है। यह दृष्टिकोण अक्सर मॉड्यूल (पुस्तकालयों / प्लगइन्स) में उपयोग किया जाता है, जिनमें से कोड को बदलना नहीं चाहिए।
मान लीजिए कि हमने निम्नलिखित फ़ंक्शन को लिखा है, किसी दिए गए सरणी के योग की गणना करते हुए:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
अब मान लें कि हम सरणी के प्रत्येक मान के साथ कुछ करना चाहते हैं, उदाहरण के लिए alert()
का उपयोग करके इसे प्रदर्शित करें। हम इस तरह से foo
के कोड में उपयुक्त बदलाव कर सकते हैं:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
alert(array[i]);
sum += array[i];
}
return sum;
}
लेकिन क्या होगा अगर हम alert()
बजाय console.log
का उपयोग करने का निर्णय लेते हैं? जाहिर है foo
के कोड को बदलना, जब भी हम प्रत्येक मूल्य के साथ कुछ और करने का निर्णय लेते हैं, तो यह एक अच्छा विचार नहीं है। foo
कोड को बदले बिना हमारे दिमाग को बदलने का विकल्प रखना ज्यादा बेहतर है। कॉलबैक के लिए यह बिल्कुल उपयोग का मामला है। हमें केवल foo
के हस्ताक्षर और शरीर को थोड़ा बदलना होगा:
function foo(array, callback) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
callback(array[i]);
sum += array[i];
}
return sum;
}
और अब हम केवल इसके मापदंडों को बदलकर foo
के व्यवहार को बदलने में सक्षम हैं:
var array = [];
foo(array, alert);
foo(array, function (x) {
console.log(x);
});
अतुल्यकालिक कार्यों के उदाहरण
JQuery में, JSON डेटा लाने के लिए $.getJSON()
विधि अतुल्यकालिक है। इसलिए, कॉलबैक में कोड पास करना सुनिश्चित करता है कि कोड JSON के लाने के बाद कहा जाता है।
$.getJSON()
सिंटैक्स:
$.getJSON( url, dataObject, successCallback );
$.getJSON()
कोड का उदाहरण:
$.getJSON("foo.json", {}, function(data) {
// data handling code
});
निम्नलिखित काम नहीं करेगा, क्योंकि डेटा-हैंडलिंग कोड संभवतः डेटा प्राप्त होने से पहले कॉल किया जाएगा, क्योंकि $.getJSON
।
$.getJSON("foo.json", {});
// data handling code
एसिंक्रोनस फ़ंक्शन का एक अन्य उदाहरण jQuery का animate()
फ़ंक्शन है। क्योंकि एनीमेशन को चलाने के लिए एक निर्दिष्ट समय लगता है, कभी-कभी एनीमेशन के बाद सीधे कुछ कोड चलाने के लिए यह वांछनीय है।
.animate()
सिंटैक्स:
jQueryElement.animate( properties, duration, callback );
उदाहरण के लिए, एक लुप्त होती एनीमेशन बनाने के लिए जिसके बाद तत्व पूरी तरह से गायब हो जाता है, निम्नलिखित कोड चलाया जा सकता है। कॉलबैक के उपयोग पर ध्यान दें।
elem.animate( { opacity: 0 }, 5000, function() {
elem.hide();
} );
यह फ़ंक्शन के समाप्त होने के बाद तत्व को सही छिपाने की अनुमति देता है। यह इससे अलग है:
elem.animate( { opacity: 0 }, 5000 );
elem.hide();
क्योंकि उत्तरार्द्ध animate()
(एक अतुल्यकालिक फ़ंक्शन) के पूरा होने का इंतजार नहीं करता है, और इसलिए तत्व अभी छिपा हुआ है, जिससे अवांछनीय प्रभाव पैदा होता है।
कॉलबैक क्या है?
यह एक सामान्य फ़ंक्शन कॉल है:
console.log("Hello World!");
जब आप एक सामान्य फ़ंक्शन को कॉल करते हैं, तो यह अपना काम करता है और फिर कॉल करने वाले को वापस नियंत्रित करता है।
हालांकि, कभी-कभी किसी फ़ंक्शन को अपना काम करने के लिए कॉल करने वाले पर नियंत्रण वापस करने की आवश्यकता होती है:
[1,2,3].map(function double(x) {
return 2 * x;
});
उपरोक्त उदाहरण में, फ़ंक्शन double
फ़ंक्शन map
लिए कॉलबैक है क्योंकि:
- फ़ंक्शन
double
को कॉलर द्वारा फ़ंक्शनmap
को दिया जाता है। - समारोह
map
फ़ंक्शन को कॉल करने की जरूरत हैdouble
क्रम अपना काम करने में में शून्य या अधिक बार।
इस प्रकार, फ़ंक्शन map
अनिवार्य रूप से कॉल को वापस double
करने के लिए हर बार कॉल करने वाले पर नियंत्रण वापस कर रहा है। इसलिए, "कॉलबैक" नाम।
कार्य एक से अधिक कॉलबैक स्वीकार कर सकते हैं:
promise.then(function onFulfilled(value) {
console.log("Fulfilled with value " + value);
}, function onRejected(reason) {
console.log("Rejected with reason " + reason);
});
यहाँ तब फ़ंक्शन then
दो कॉलबैक कार्यों को स्वीकार करता है, onFulfilled
और onRejected
। इसके अलावा, इन दो कॉलबैक कार्यों में से केवल एक को वास्तव में कहा जाता है।
क्या अधिक दिलचस्प बात यह है कि कॉलबैक में से किसी को कॉल करने से पहले फ़ंक्शन then
वापस आ जाता है। इसलिए, मूल फ़ंक्शन वापस आने के बाद भी कॉलबैक फ़ंक्शन को कॉल किया जा सकता है।
निरंतरता (तुल्यकालिक और अतुल्यकालिक)
कॉलबैक का उपयोग किसी विधि के पूर्ण होने के बाद कोड निष्पादित करने के लिए किया जा सकता है:
/** * @arg {Function} then continuation callback */ function doSomething(then) { console.log('Doing something'); then(); } // Do something, then execute callback to log 'done' doSomething(function () { console.log('Done'); }); console.log('Doing something else'); // Outputs: // "Doing something" // "Done" // "Doing something else"
doSomething()
मेथड ऊपर कॉलबैक के साथ सिंक्रोनाइज़ करता है - निष्पादन ब्लॉक जब तक doSomething()
रिटर्न होता है, यह सुनिश्चित करता है कि doSomething()
से पहले कॉलबैक निष्पादित हो जाए।
कॉलबैक का उपयोग कोड को एसिंक्रोनस रूप से निष्पादित करने के लिए भी किया जा सकता है:
doSomethingAsync(then) { setTimeout(then, 1000); console.log('Doing something asynchronously'); } doSomethingAsync(function() { console.log('Done'); }); console.log('Doing something else'); // Outputs: // "Doing something asynchronously" // "Doing something else" // "Done"
then
कॉलबैक को doSomething()
विधियों की निरंतरता माना जाता है। किसी फ़ंक्शन में अंतिम निर्देश के रूप में कॉलबैक प्रदान करना एक टेल-कॉल कहा जाता है, जिसे ES2015 दुभाषियों द्वारा अनुकूलित किया जाता है ।
हैंडलिंग और नियंत्रण-प्रवाह शाखा में त्रुटि
कॉलबैक का उपयोग अक्सर त्रुटि हैंडलिंग प्रदान करने के लिए किया जाता है। यह नियंत्रण प्रवाह शाखा का एक रूप है, जहां कुछ निर्देश केवल तब निष्पादित होते हैं जब कोई त्रुटि होती है:
const expected = true;
function compare(actual, success, failure) {
if (actual === expected) {
success();
} else {
failure();
}
}
function onSuccess() {
console.log('Value was expected');
}
function onFailure() {
console.log('Value was unexpected/exceptional');
}
compare(true, onSuccess, onFailure);
compare(false, onSuccess, onFailure);
// Outputs:
// "Value was expected"
// "Value was unexpected/exceptional"
compare()
में कोड निष्पादन compare()
ऊपर compare()
की दो संभावित शाखाएँ हैं: success
जब अपेक्षित और वास्तविक मूल्य समान होते हैं, और error
तब error
जब वे भिन्न होते हैं। यह विशेष रूप से उपयोगी है जब नियंत्रण प्रवाह को कुछ अतुल्यकालिक अनुदेश के बाद शाखा करना चाहिए:
function compareAsync(actual, success, failure) {
setTimeout(function () {
compare(actual, success, failure)
}, 1000);
}
compareAsync(true, onSuccess, onFailure);
compareAsync(false, onSuccess, onFailure);
console.log('Doing something else');
// Outputs:
// "Doing something else"
// "Value was expected"
// "Value was unexpected/exceptional"
यह ध्यान दिया जाना चाहिए, कई कॉलबैक को पारस्परिक रूप से अनन्य होने की आवश्यकता नहीं है - दोनों तरीकों को बुलाया जा सकता है। इसी तरह, compare()
कॉलबैक के साथ लिखी जा सकती है जो वैकल्पिक हैं (डिफ़ॉल्ट मान के रूप में एक noop का उपयोग करके - नल पैटर्न देखें)।
कॉलबैक और `यह`
अक्सर कॉलबैक का उपयोग करते समय आप एक विशिष्ट संदर्भ तक पहुंच चाहते हैं।
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg); // <= will fail because "this" is undefined
});
}
var s = new SomeClass("hello", someElement);
समाधान
bind
प्रयोग करेंbind
प्रभावी रूप से एक नया समारोह है कि सेट उत्पन्न करता हैthis
के लिए जो कुछ भी पारित किया गया था करने के लिएbind
तो मूल कार्य कहता है।function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', function() { console.log(this.msg); }.bind(this)); // <=- bind the function to `this` }
तीर के कार्यों का उपयोग करें
एरो फ़ंक्शंस वर्तमान में
this
संदर्भ को स्वचालित रूप से बांधते हैं।function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click',() => { // <=- arrow function binds `this` console.log(this.msg); }); }
अक्सर आप किसी फ़ंक्शन फ़ंक्शन को कॉल करना चाहते हैं, आदर्श रूप से फ़ंक्शन पर ईवेंट के लिए पारित किए गए किसी भी तर्क को पारित करते हैं।
समाधान:
बाँध का प्रयोग करें
function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', this.handleClick.bind(this)); } SomeClass.prototype.handleClick = function(event) { console.log(event.type, this.msg); };
तीर फ़ंक्शंस और बाकी ऑपरेटर का उपयोग करें
function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', (...a) => this.handleClick(...a)); } SomeClass.prototype.handleClick = function(event) { console.log(event.type, this.msg); };
विशेष रूप से DOM ईवेंट श्रोताओं के लिए आप
EventListener
इंटरफ़ेस लागू कर सकते हैंfunction SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', this); } SomeClass.prototype.handleEvent = function(event) { var fn = this[event.type]; if (fn) { fn.apply(this, arguments); } }; SomeClass.prototype.click = function(event) { console.log(this.msg); };
एरो फ़ंक्शन का उपयोग करके कॉलबैक
कॉलबैक फ़ंक्शन के रूप में एरो फ़ंक्शन का उपयोग करना कोड की लाइनों को कम कर सकता है।
तीर फ़ंक्शन के लिए डिफ़ॉल्ट सिंटैक्स है
() => {}
इसे कॉलबैक के रूप में इस्तेमाल किया जा सकता है
उदाहरण के लिए यदि हम किसी सरणी में सभी तत्वों को प्रिंट करना चाहते हैं [1,2,3,4,5]
बिना एरो फंक्शन के, कोड इस तरह दिखेगा
[1,2,3,4,5].forEach(function(x){
console.log(x);
}
एरो फंक्शन के साथ इसे कम किया जा सकता है
[1,2,3,4,5].forEach(x => console.log(x));
यहां कॉलबैक फ़ंक्शन function(x){console.log(x)}
को x=>console.log(x)
में घटा दिया गया है