2010-10-15 22 views
9

यह उदाहरण जावास्क्रिप्ट है, क्योंकि वहीं मैं कॉलबैक का उपयोग कर रहा हूं। मैं समझना चाहता हूं कि वे निम्न स्तर पर कैसे काम करते हैं।कॉलबैक हमेशा असीमित हैं?

नीचे दिए गए उदाहरण में, मैं उम्मीद करता हूं कि सबकुछ क्रम में हो और "चरण 3" और "चरण 4" से पहले "वापस कॉल करना" हो। यह मुझे समझ में आता है, क्योंकि निष्पादन के एक धागे पर सबकुछ किया जाता है। कोई चालबाजी नहीं है। एकमात्र चीज जो विशेष प्रकार की है वह यह है कि आपने किसी फ़ंक्शन को किसी अन्य फ़ंक्शन में पास कर दिया है।

function main() { 
    console.log("step 1"); 
    console.log("step 2"); 
    doSomething(myCallBack); 
    console.log("step 4"); 
} 

function doSomething(f) { 
    accessTheDatabase(); // this could take a while 
    console.log("step 3"); 
    f(); // done - now call back 
} 

function myCallBack() { 
    console.log("calling back!"); 
} 

आप कैसे doSomething अतुल्यकालिक ताकि "चरण 4" से पहले क्रियान्वित किया जा सकता है, या के साथ, "चरण 3" समानांतर में होगा?

मुझे लगता है कि अगर doSomething किसी भी तरह से असीमित रूप से कहा जाता है, तो यह एक अलग धागे पर होना होगा, नहीं? और यदि ऐसा है, तो जब यह खत्म हो जाता है और फिर myCallBack पर कॉल करता है, कॉलबैक दूसरे धागे पर या मुख्य धागे पर होता है? यदि यह मुख्य धागे पर होता है, तो दूसरे थ्रेड को कॉलबैक फ़ंक्शन में पॉइंटर की आवश्यकता क्यों होती है? इंटर-थ्रेड कॉल कैसे काम करता है?

+0

मुझे लगता है कि यह एक ब्राउज़र में नहीं चल रहा है, है ना? क्योंकि ब्राउज़र में, कोई भी AJAX कॉल अनिवार्य रूप से असीमित है ... –

+2

@Dean, सभी XHR अनुरोधों में से पहला सिंक्रोनस (अनुरोध पैरामीटर के आधार पर) द्वारा किया जा सकता है। दूसरा, यदि आप प्रश्न पढ़ते हैं (और इसके उदाहरण कोड को देखते हैं), यह अजाक्स के बारे में नहीं है। – eyelidlessness

+0

@ डीन यह ब्राउज़र में चल रहा है या नहीं। मुझे यह पता लगाने में सबसे अधिक दिलचस्पी है कि क्या कॉलबैक फ़ंक्शन मुख्य थ्रेड या दूसरे थ्रेड पर निष्पादित किया गया है जो कॉलबैक फ़ंक्शन पॉइंटर को पैरामीटर के रूप में पारित किया गया था। –

उत्तर

11

WebWorkers एक तरफ, ब्राउज़र में जावास्क्रिप्ट प्रोग्रामिंग मॉडल पूरी तरह से सिंगल-थ्रेडेड है। आप window.setTimeout का उपयोग करके अपने कॉल कुछ हद तक अतुल्यकालिक बना सकते हैं:

window.setTimeout(doSomething, 0, myCallBack); 

यह प्रभावी रूप से टाइमर कतार पर कॉल doSomething(myCallBack) देता है, और 0 या अधिक मिलीसेकेंड बीत के बाद, यह अंततः लागू हो जाएगी। हालांकि, जावास्क्रिप्ट में सभी एसिंक्रोनस कॉल के साथ, किसी भी एसिंक्रोनस कॉलबैक को लागू करने से पहले आपको निष्पादन संदर्भ को छोड़ना होगा; यानी, टाइमर कतार संसाधित नहीं की जाएगी (और इसलिए doSomething(myCallBack) लागू नहीं किया जाएगा) जब तक कि आपके main() फ़ंक्शन समाप्त नहीं हो जाते हैं, यह मानते हुए कि यह आपकी जावास्क्रिप्ट का अंत है।

इस setTimeout-आधारित दृष्टिकोण का एक दुर्भाग्यपूर्ण परिणाम यह है कि doSomething(myCallBack)console.log("step 4") के साथ समानांतर में शामिल नहीं होता है। दूसरी ओर, XMLHttpRequest.send पर विचार करें; यह कॉल करने के बाद, जब आपका ब्राउज़र HTTP अनुरोध जारी करता है तो आपका शेष जेएस निष्पादित करना जारी रख सकता है। आपकी स्क्रिप्ट को onreadystatechange हैंडलर निष्पादित करने से पहले निष्पादन समाप्त करने की आवश्यकता है, लेकिन जेएस निष्पादित करते समय अधिकांश HTTP कनेक्शन कार्य समानांतर में हो सकता है।

+0

'XMLHttpRequest.send' मामले में, मुझे लगता है कि किसी अन्य धागे पर होता है। जब यह हो जाता है और 'onreadystatechange' हैंडलर निष्पादित करता है, तो यह धागा क्या होता है? –

+1

यह मुख्य जावास्क्रिप्ट थ्रेड पर होता है। कार्यान्वयन के अनुसार, यह कोई धागा हो सकता है, लेकिन अवधारणात्मक जावास्क्रिप्ट (और उस मामले के लिए डोम) एक धागे के भीतर निष्पादित करता है। – ide

+1

मुझे लगता है कि भ्रमित करने वाला हिस्सा यह है कि इसे "कॉलबैक" कहा जाता है। वह, मेरे लिए, "यहां एक समारोह है, कृपया इसे कॉल करें जब आप अपनी काम कर रहे हैं। मैं अपनी खुद की चीज कर दूंगा।" जब वास्तव में, ब्राउज़र AJAX कॉल को समाप्त करता है और फिर मुख्य थ्रेड (किस तंत्र के माध्यम से?) में बाधा डालता है और मुख्य धागा स्वयं उस कॉल को कॉल करता है जिसे वह कॉलबैक के रूप में पंजीकृत करता है। क्या मैं सही हू? –

0

आपको ऐसा करने के लिए निष्पादन के कई धागे की आवश्यकता होगी, जो मुझे विश्वास नहीं है कि आप जावास्क्रिप्ट में कर सकते हैं (हालांकि अगर मैं गलत हूं तो मुझे सही करें)। हालांकि अगर आप सी/सी ++ प्रोग्राम लिख रहे थे, तो pthreads पैकेज (या मैक ओएस एक्स 10.6 पर libdispatch) देखें।

संपादित करें: "थ्रेड जावास्क्रिप्ट" के लिए Google खोज कुछ संभवतः दिलचस्प परिणाम बदलती है।

0

कॉलबैक का उपयोग करके आप जिस तरह से हैं (फ़ंक्शन घोषणा नाम या फ़ंक्शन अभिव्यक्ति चर नाम किसी अन्य फ़ंक्शन के लिए तर्क के रूप में), वे तुल्यकालिक हैं। उन्हें अतुल्यकालिक बनाने के लिए, आप उन्हें setTimeout में लपेट सकते हैं।

+0

@trinithis, मैं गलत कैसे हूँ? – eyelidlessness

5

हम्म .. कुछ गलत दिखता है (मैंने v छोटी जावास्क्रिप्ट किया है): आप मेरे कैलबैक को फ़ंक्शन में पास करते हैं कुछ() लेकिन आप इसे वापस कॉल नहीं करते हैं !? आपको f() के अंदर f() के अंदर कॉल करना होगा (या इसे किसी अन्य फ़ंक्शन पर पास करना होगा जो आपके लंबे ऑपरेशन पूर्ण होने के बाद इसे वापस कॉल करेगा .. और कोई कॉलबैक स्वाभाविक रूप से असीमित नहीं है - आपके मामले में आप इसे सब कुछ चला रहे हैं उसी धागे पर (भले ही accessTheDatabase() असीमित है, इस मामले में यह तुरंत वापस आ जाएगा!) - तो यह अभी भी चरण 1, चरण 2, चरण 3, चरण 4 पर जायेगा। मेरा मानना ​​है कि आप चाहते हैं:

function main() { 
    console.log("step 1"); 
    console.log("step 2"); 
    doSomething(myCallBack); 
    console.log("step 4"); 
} 

function doSomething(f) { 
    accessTheDatabase(f); // assuming this is an asynchronous operation and calls the callback f once done 
} 

function myCallBack() { 
    console.log("step 3"); 
} 

अपने प्रश्न के दूसरे भाग के जवाब में: कॉलबैक जिस पर चलाया जाएगा कभी थ्रेड आप से बुला रहे हैं - एक और धागा आप करने के लिए होगा पर एक कॉलबैक को चलाने के लिए उस धागे में शामिल हों() पहले थ्रेड() या startinvoke() कॉलबैक - हालांकि आपके कॉलबैक को उस थ्रेड पर चलाने के लिए पहले से कुछ बनाया जा सकता है, जिसे आप इसे चलाने के लिए चाहते हैं (अक्सर यूआई धागे के साथ मामला) नोट: यह पहले से ही हो सकता है कि AccessDDatabase() उस थ्रेड पर कॉलबैक चलाता है जिसे इसे बुलाया जाता है - उपर्युक्त विधियों में से एक का उपयोग करके ...

+0

आप सही हैं! पकड़ के लिए धन्यवाद। –

+0

मेरी खुशी, अगर यह है तो इसे उत्तर के रूप में चिह्नित करें :) – markmnl

+0

आपके प्रश्न के दूसरे भाग के लिए अद्यतन उत्तर - जो धागा यह चल रहा है – markmnl

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