जावास्क्रिप्ट में कॉलबैक फ़ंक्शन की बेहतर समझ प्राप्त करना


163

मैं एक फ़ंक्शन को कॉलबैक के रूप में एक फ़ंक्शन में पास करना और इसे निष्पादित करना समझता हूं, लेकिन मैं ऐसा करने के लिए सबसे अच्छा कार्यान्वयन नहीं समझ रहा हूं। मैं इस तरह से एक बहुत ही बुनियादी उदाहरण की तलाश में हूँ:

var myCallBackExample = {
    myFirstFunction : function( param1, param2, callback ) {
        // Do something with param1 and param2.
        if ( arguments.length == 3 ) {
            // Execute callback function.
            // What is the "best" way to do this?
        }
    },
    mySecondFunction : function() {
        myFirstFunction( false, true, function() {
            // When this anonymous function is called, execute it.
        });
    }
};

MyFirstFunction में, यदि मैं नया कॉलबैक () वापस करता हूं, तो यह अनाम फ़ंक्शन को काम करता है और निष्पादित करता है, लेकिन यह मेरे लिए सही दृष्टिकोण की तरह प्रतीत नहीं होता है।


किस अर्थ में ठीक है? आमतौर पर कॉलबैक का उपयोग इवेंट हैंडलर के लिए किया जाता है - सबसे विशेष रूप से अजाक्स कॉल, जो अतुल्यकालिक हैं - मूल रूप से ऐसी चीजें जहां आप नहीं जानते कि कब (या अगर) एक रिस्पॉन्स आएगा।
क्लेटस

2
वैसे तर्कों की तरह सरणी है, लेकिन सरणी नहीं है, इसलिए आप तर्क नहीं कर सकते हैं। गति लेकिन आप इसे स्लाइस विधि का उपयोग करके एक सरणी में बदल सकते हैं ...
पॉल

1
@ अंपुल, हालांकि आप सही हैं कि argumentsयह एक सरणी नहीं है, फिर भी आप इसकी लंबाई का संदर्भ arguments.lengthदे सकते हैं - इसे आज़माएं। यह संपत्ति वास्तव में पारित तर्कों की संख्या को संदर्भित करती है, और जरूरी नहीं कि फ़ंक्शन हस्ताक्षर में मापदंडों की संख्या हो।
hotshot309

जवाबों:


132

आप बस कह सकते हैं

callback();

callयदि आप thisकॉलबैक के भीतर मूल्य समायोजित करना चाहते हैं तो वैकल्पिक रूप से आप इस विधि का उपयोग कर सकते हैं ।

callback.call( newValueForThis);

समारोह के अंदर thisजो भी होगा newValueForThis


91

यदि कॉलबैक मौजूद है, तो आपको जांचना चाहिए और एक निष्पादन योग्य कार्य है:

if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
}

बहुत सारे पुस्तकालय (jQuery, dojo, आदि) अपने अतुल्यकालिक कार्यों के लिए एक समान पैटर्न का उपयोग करते हैं, साथ ही सभी async कार्यों के लिए नोड (jj) आमतौर पर (नोड्ज गुजरता है errorऔर dataकॉलबैक के लिए)। उनके स्रोत कोड को देखने से मदद मिलेगी!


आप callbackस्ट्रिंग क्यों करते हैं और फिर इसके प्रकार की जांच करते हैं? क्या इससे प्रदर्शन बढ़ेगा? यह प्रकार की जाँच करने की तरह है, यह जाँचना कि क्या परिवर्तित बूलियन सही है और फिर उसके प्रकार को फिर से जाँचना और स्ट्रिंग के खिलाफ परीक्षण करना ... क्या मैं समझा सकता हूँ?
सिर दर्द

मैं उत्सुक हूं कि आपको कॉलबैक के लिए पहले दावे की आवश्यकता क्यों है ... क्या यह अशक्त या अपरिभाषित की जांच करना है? typeof(callback)कि आप के लिए हासिल नहीं होगा ? typeof(null) === "Object",typeof("undefined") === "undefined"
PJH

1
शॉर्ट-सर्किट और। यदि कॉलबैक मौजूद नहीं है, तो इसके प्रकार की गणना करने से परेशान न हों। हालाँकि, आप सही कह रहे हैं। यह टाइपोफ़ () के साथ आवश्यक नहीं है, लेकिन मैं एक jsperf करूँगा और देखूंगा कि शॉर्ट-सर्किट इसके लायक है या नहीं।
अरुणजीतसिंह

@headacheCoder - callbackको एक स्ट्रिंग में नहीं डाला जा रहा है, इसका प्रकार यह देखने के लिए जांचा जा रहा है कि क्या यह एक फ़ंक्शन है, इससे पहले कि यह कहा जाता है। कोड संभवतः callbackएक तर्क के रूप में स्वीकार करता है, और अनिश्चित है कि तर्क एक कॉल करने योग्य प्रकार का है - या शायद तर्क बहुरूपता का एक रूप प्रदान करने के प्रयास में विभिन्न प्रकार के होते हैं जहां कोड अलग-अलग typeofतर्क पर अलग-अलग प्रतिक्रिया दे सकता है।
लीजी

34

किसी कार्य को निष्पादित करने के लिए 3 मुख्य संभावनाएं हैं:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. कॉलबैक (तर्क_1, तर्क 2);
  2. callback.call (some_object, तर्क_1, तर्क 2);
  3. callback.apply (some_object, [तर्क_1, तर्क_2]);

आपके द्वारा चुनी गई विधि निर्भर करती है कि क्या:

  1. आपके पास ऐरे में या अलग-अलग चर के रूप में संग्रहीत तर्क हैं।
  2. आप उस फ़ंक्शन को किसी ऑब्जेक्ट के संदर्भ में कॉल करना चाहते हैं। इस स्थिति में, उस कॉलबैक में "यह" कीवर्ड का उपयोग करके कॉल () या लागू () में तर्क के रूप में पारित वस्तु को संदर्भित किया जाएगा। यदि आप ऑब्जेक्ट संदर्भ को पास नहीं करना चाहते हैं, तो अशक्त या अपरिभाषित का उपयोग करें। बाद के मामले में वैश्विक वस्तु का उपयोग "इस" के लिए किया जाएगा।

फंक्शन के लिए डॉक्स। फॉल , फंक्शन.प्पली


6

कॉलबैक संकेतों के बारे में हैं और "नया" ऑब्जेक्ट इंस्टेंस बनाने के बारे में है।

इस मामले में सिर्फ "कॉलबैक ();" "नए कॉलबैक ()" की तुलना में, क्योंकि आप वैसे भी रिटर्न वैल्यू के साथ कुछ नहीं कर रहे हैं।

(और तर्क.लगाव = = 3 परीक्षण वास्तव में क्लंकी, fwiw है, यह जांचने के लिए बेहतर है कि कॉलबैक परम मौजूद है और एक फ़ंक्शन है।)


6

उचित कार्यान्वयन होगा:

if( callback ) callback();

यह कॉलबैक पैरामीटर को वैकल्पिक बनाता है।


क्या होगा यदि कॉलबैक तर्क एक फ़ंक्शन नहीं है?
याकी क्लेन

2

आप उपयोग कर सकते हैं:

if (callback && typeof(callback) === "function") {
    callback();
}

नीचे का उदाहरण थोड़ा और व्यापक है:

function mySandwich(param1, param2, callback) {
  alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
  var sandwich = {
      toppings: [param1, param2]
    },
    madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;
  if (callback && typeof(callback) === "function") {
    callback.apply(sandwich, [madeCorrectly]);
  }
}

mySandwich('ham', 'cheese', function(correct) {
  if (correct) {
    alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");
  } else {
    alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");
  }
});


1

यहाँ एक मूल उदाहरण दिया गया callback()है जो जावास्क्रिप्ट में कार्य को समझाता है :

var x = 0;

function testCallBack(param1, param2, callback) {
  alert('param1= ' + param1 + ', param2= ' + param2 + ' X=' + x);
  if (callback && typeof(callback) === "function") {
    x += 1;
    alert("Calla Back x= " + x);
    x += 1;
    callback();
  }
}

testCallBack('ham', 'cheese', function() {
  alert("Function X= " + x);
});

JSFiddle


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.