किसी फ़ंक्शन के अंदर इसे संशोधित करने के बाद मेरा वेरिएबल अनलग्ड क्यों है? - एसिंक्रोनस कोड संदर्भ

May 15 2014

निम्नलिखित उदाहरणों को देखते हुए, outerScopeVarसभी मामलों में अपरिभाषित क्यों है ?

var outerScopeVar;

var img = document.createElement('img');
img.onload = function() {
    outerScopeVar = this.width;
};
img.src = 'lolcat.png';
alert(outerScopeVar);

var outerScopeVar;
setTimeout(function() {
    outerScopeVar = 'Hello Asynchronous World!';
}, 0);
alert(outerScopeVar);

// Example using some jQuery
var outerScopeVar;
$.post('loldog', function(response) {
    outerScopeVar = response;
});
alert(outerScopeVar);

// Node.js example
var outerScopeVar;
fs.readFile('./catdog.html', function(err, data) {
    outerScopeVar = data;
});
console.log(outerScopeVar);

// with promises
var outerScopeVar;
myPromise.then(function (response) {
    outerScopeVar = response;
});
console.log(outerScopeVar);

// geolocation API
var outerScopeVar;
navigator.geolocation.getCurrentPosition(function (pos) {
    outerScopeVar = pos;
});
console.log(outerScopeVar);

undefinedइन सभी उदाहरणों में इसका उत्पादन क्यों होता है ? मुझे वर्कअराउंड नहीं चाहिए, मैं जानना चाहता हूं कि ऐसा क्यों हो रहा है।


नोट: यह जावास्क्रिप्ट अतुल्यकालिकता के लिए एक विहित प्रश्न है । इस प्रश्न को सुधारने और अधिक सरलीकृत उदाहरण जोड़ने के लिए स्वतंत्र महसूस करें, जिसे समुदाय पहचान सकता है।

जवाब

605 FabrícioMatté May 15 2014 at 06:55

एक शब्द का जवाब: अतुल्यकालिकता

भूमिकाएँ

इस विषय को, स्टैक ओवरफ्लो में, कम से कम एक-दो हजार बार पुन: प्रसारित किया गया है। इसलिए, सबसे पहले मैं कुछ अत्यंत उपयोगी संसाधनों को इंगित करना चाहूंगा:


सवाल का जवाब हाथ में

आइए पहले सामान्य व्यवहार का पता लगाएं। सभी उदाहरणों में, outerScopeVarएक फ़ंक्शन के अंदर संशोधित किया गया है । उस फ़ंक्शन को स्पष्ट रूप से तुरंत निष्पादित नहीं किया जाता है, इसे एक तर्क के रूप में सौंपा या पारित किया जा रहा है। जिसे हम कॉलबैक कहते हैं ।

अब सवाल यह है कि उस कॉलबैक को कब कहा जाता है?

यह केस पर निर्भर करता है। आइए फिर से कुछ सामान्य व्यवहार का पता लगाने की कोशिश करें:

  • img.onloadभविष्य में किसी समय कहा जा सकता है , जब (और यदि) छवि सफलतापूर्वक लोड हो गई है।
  • setTimeoutविलंब समाप्त होने के बाद और समय समाप्त होने तक रद्द नहीं किया गया है, भविष्य में कुछ समय के लिए कहा जा सकता है clearTimeout। नोट: 0देरी के रूप में उपयोग करने पर भी , सभी ब्राउज़रों में न्यूनतम टाइमआउट देरी की टोपी होती है (एचटीएमएल 5 कल्पना में 4ms तक निर्दिष्ट)।
  • jQuery $.postके कॉलबैक को भविष्य में , (और यदि) Ajax के अनुरोध को सफलतापूर्वक पूरा किया जा सकता है।
  • Node.js को भविष्य में कभीfs.readFile भी कॉल किया जा सकता है , जब फ़ाइल को सफलतापूर्वक पढ़ा गया हो या किसी त्रुटि को फेंक दिया गया हो।

सभी मामलों में, हमारे पास एक कॉलबैक है जो भविष्य में कभी भी चल सकता है । यह "भविष्य में कुछ समय" है जिसे हम अतुल्यकालिक प्रवाह के रूप में संदर्भित करते हैं

अतुल्यकालिक निष्पादन को तुल्यकालिक प्रवाह से बाहर धकेल दिया जाता है। अर्थात, एसिंक्रोनस कोड कभी भी निष्पादित नहीं करेगा जबकि सिंक्रोनस कोड स्टैक निष्पादित हो रहा है। यह जावास्क्रिप्ट का एकल-पिरोया जाने का अर्थ है।

अधिक विशेष रूप से, जब जेएस इंजन निष्क्रिय होता है - (क) सिंक्रोनस कोड के स्टैक को निष्पादित नहीं करना - यह उन घटनाओं के लिए मतदान करेगा, जो अतुल्यकालिक कॉलबैक (जैसे कि समय समाप्त हो गया, नेटवर्क प्रतिक्रिया प्राप्त) को ट्रिगर कर सकते हैं और उन्हें एक के बाद एक निष्पादित कर सकते हैं। इसे इवेंट लूप माना जाता है ।

अर्थात्, हाथ से खींची गई लाल आकृतियों में हाइलाइट किया गया एसिंक्रोनस कोड अपने संबंधित कोड ब्लॉक में सभी शेष सिंक्रोनस कोड निष्पादित होने के बाद ही निष्पादित हो सकता है:

संक्षेप में, कॉलबैक फ़ंक्शंस को सिंक्रोनाइज़ किया जाता है लेकिन एसिंक्रोनस रूप से निष्पादित किया जाता है। आप बस एक अतुल्यकालिक फ़ंक्शन के निष्पादन पर भरोसा नहीं कर सकते हैं जब तक कि आप यह नहीं जानते कि इसे निष्पादित किया गया है, और यह कैसे करना है?

यह वास्तव में सरल है। तर्क जो अतुल्यकालिक फ़ंक्शन निष्पादन पर निर्भर करता है, उसे इस अतुल्यकालिक फ़ंक्शन के अंदर से शुरू / बुलाया जाना चाहिए। उदाहरण के लिए, कॉलबैक फ़ंक्शन के अंदर भी alerts और console.logs को ले जाना अपेक्षित परिणाम का उत्पादन करेगा, क्योंकि परिणाम उस बिंदु पर उपलब्ध है।

अपने स्वयं के कॉलबैक तर्क को लागू करना

अक्सर आपको एक एसिंक्रोनस फ़ंक्शन से परिणाम के साथ अधिक चीजें करने की आवश्यकता होती है या परिणाम के साथ अलग-अलग चीजें करते हैं, जिसके आधार पर एसिंक्रोनस फ़ंक्शन को कहा जाता है। चलिए थोड़ा और जटिल उदाहरण पेश करते हैं:

var outerScopeVar;
helloCatAsync();
alert(outerScopeVar);

function helloCatAsync() {
    setTimeout(function() {
        outerScopeVar = 'Nya';
    }, Math.random() * 2000);
}

नोट: मैं setTimeoutजेनेरिक एसिंक्रोनस फ़ंक्शन के रूप में एक यादृच्छिक देरी के साथ उपयोग कर रहा हूं , वही उदाहरण अजाक्स readFile, onloadऔर किसी अन्य एसिंक्रोनस प्रवाह पर लागू होता है ।

यह उदाहरण स्पष्ट रूप से अन्य उदाहरणों के समान मुद्दे से ग्रस्त है, यह तब तक इंतजार नहीं कर रहा है जब तक अतुल्यकालिक फ़ंक्शन निष्पादित नहीं होता है।

आइए इससे निपटने के लिए अपने स्वयं के कॉलबैक सिस्टम को लागू करें। सबसे पहले, हम उस बदसूरत से छुटकारा पा लेते हैं outerScopeVarजो इस मामले में पूरी तरह से बेकार है। फिर हम एक पैरामीटर जोड़ते हैं जो एक फ़ंक्शन तर्क, हमारे कॉलबैक को स्वीकार करता है। जब एसिंक्रोनस ऑपरेशन खत्म हो जाता है, तो हम इस कॉलबैक को परिणाम पास करते हैं। कार्यान्वयन (कृपया टिप्पणियों को क्रम में पढ़ें):

// 1. Call helloCatAsync passing a callback function,
//    which will be called receiving the result from the async operation
helloCatAsync(function(result) {
    // 5. Received the result from the async function,
    //    now do whatever you want with it:
    alert(result);
});

// 2. The "callback" parameter is a reference to the function which
//    was passed as argument from the helloCatAsync call
function helloCatAsync(callback) {
    // 3. Start async operation:
    setTimeout(function() {
        // 4. Finished async operation,
        //    call the callback passing the result as argument
        callback('Nya');
    }, Math.random() * 2000);
}

उपरोक्त उदाहरण का कोड स्निपेट:

// 1. Call helloCatAsync passing a callback function,
//    which will be called receiving the result from the async operation
console.log("1. function called...")
helloCatAsync(function(result) {
    // 5. Received the result from the async function,
    //    now do whatever you want with it:
    console.log("5. result is: ", result);
});

// 2. The "callback" parameter is a reference to the function which
//    was passed as argument from the helloCatAsync call
function helloCatAsync(callback) {
    console.log("2. callback here is the function passed as argument above...")
    // 3. Start async operation:
    setTimeout(function() {
    console.log("3. start async operation...")
    console.log("4. finished async operation, calling the callback, passing the result...")
        // 4. Finished async operation,
        //    call the callback passing the result as argument
        callback('Nya');
    }, Math.random() * 2000);
}

ज्यादातर वास्तविक उपयोग के मामलों में, DOM API और अधिकांश लाइब्रेरी पहले से ही कॉलबैक कार्यक्षमता ( helloCatAsyncइस प्रदर्शनकारी उदाहरण में कार्यान्वयन) प्रदान करते हैं। आपको केवल कॉलबैक फ़ंक्शन को पास करना होगा और यह समझना होगा कि यह समकालिक प्रवाह से बाहर निकल जाएगा, और इसके लिए आपके कोड को फिर से व्यवस्थित करेगा।

आप यह भी देखेंगे कि अतुल्यकालिक प्रकृति के कारण, returnअतुल्यकालिक प्रवाह से वापस तुल्यकालिक प्रवाह के लिए एक मूल्य असंभव है जहां कॉलबैक को परिभाषित किया गया था, क्योंकि अतुल्यकालिक कॉलबैक को तब निष्पादित किया जाता है जब सिंक्रोनस कोड पहले ही निष्पादित करना समाप्त कर देता है।

returnएक अतुल्यकालिक कॉलबैक से आईएनजी के बजाय , आपको कॉलबैक पैटर्न का उपयोग करना होगा, या ... वादे।

वादे

यद्यपि वेनिला जेएस के साथ कॉलबैक नरक को बनाए रखने के तरीके हैं , वादे लोकप्रियता में बढ़ रहे हैं और वर्तमान में ईएस 6 में मानकीकृत किए जा रहे हैं ( वादा - एमडीएन देखें )।

वादे (उर्फ फ्यूचर्स) अतुल्यकालिक कोड को पढ़ने के लिए एक अधिक रैखिक, और इस प्रकार सुखद, प्रदान करते हैं, लेकिन उनकी संपूर्ण कार्यक्षमता को समझाते हुए इस प्रश्न के दायरे से बाहर हैं। इसके बजाय, मैं दिलचस्पी के लिए इन उत्कृष्ट संसाधनों को छोड़ दूँगा:


जावास्क्रिप्ट अतुल्यकालिकता के बारे में अधिक पढ़ने की सामग्री


नोट: मैंने इस उत्तर को समुदाय विकी के रूप में चिह्नित किया है, इसलिए कम से कम 100 प्रतिष्ठा वाले कोई भी व्यक्ति इसे संपादित और सुधार सकता है! कृपया इस उत्तर को बेहतर बनाने के लिए स्वतंत्र महसूस करें, या यदि आप चाहें तो एक नया उत्तर प्रस्तुत करें।

मैं इस सवाल को एक अतुल्यकालिक मुद्दों का जवाब देने के लिए एक विहित विषय में बदलना चाहता हूं, जो अजाक्स से असंबंधित है ( एक AJAX कॉल से प्रतिक्रिया कैसे लौटाएं? उसके लिए), इसलिए इस विषय को यथासंभव अच्छे और उपयोगी होने के लिए आपकी मदद की आवश्यकता है !

158 Matt May 29 2014 at 16:09

Fabrício का जवाब हाजिर है; लेकिन मैं कुछ कम तकनीकी के साथ उनके जवाब को पूरक करना चाहता था, जो कि एसिंक्रोनसिटी की अवधारणा को समझाने में मदद करने के लिए एक समानता पर ध्यान केंद्रित करता है


एक सादृश्य ...

कल, मैं जो काम कर रहा था वह एक सहयोगी से कुछ जानकारी के लिए आवश्यक था। मैंने उसे ऊपर उठाया; यहाँ बातचीत कैसे हुई:

मेरे : हाय बॉब, मुझे पता है कि कैसे हम जरूरत foo 'घ बार ' पिछले सप्ताह d। जिम इस पर एक रिपोर्ट चाहते हैं, और आप केवल एक ही हैं जो इसके बारे में विवरण जानते हैं।

बॉब : ज़रूर बात है, लेकिन मुझे लगभग 30 मिनट लगेंगे?

मैं : बहुत अच्छा बॉब। जब आपको जानकारी मिली हो तो मुझे एक अंगूठी वापस दें!

इस बिंदु पर, मैंने फोन को लटका दिया। चूँकि मुझे अपनी रिपोर्ट पूरी करने के लिए बॉब से जानकारी की आवश्यकता थी, इसलिए मैंने रिपोर्ट छोड़ दी और इसके बदले कॉफ़ी लेने चला गया, तब मैंने कुछ ईमेल को पकड़ा। 40 मिनट बाद (बॉब धीमा है), बॉब ने वापस बुलाया और मुझे वह जानकारी दी जिसकी मुझे जरूरत थी। इस बिंदु पर, मैंने अपनी रिपोर्ट के साथ अपना काम फिर से शुरू कर दिया, क्योंकि मेरे पास सभी आवश्यक जानकारी थी।


कल्पना करें कि क्या बातचीत इस तरह से चली गई थी;

मेरे : हाय बॉब, मुझे पता है कि कैसे हम जरूरत foo 'घ बार ' पिछले सप्ताह d। जिम उस पर एक रिपोर्ट चाहते हैं, और आप केवल एक ही हैं जो इसके बारे में विवरण जानते हैं।

बॉब : ज़रूर बात है, लेकिन मुझे लगभग 30 मिनट लगेंगे?

मैं : बहुत अच्छा बॉब। मैं इंतजार करूँगा।

और मैं वहीं बैठ कर इंतजार करने लगा। और इंतजार किया। और इंतजार किया। 40 मिनट के लिए। इंतजार करने के सिवाय कुछ नहीं। आखिरकार, बॉब ने मुझे जानकारी दी, हमने हंगामा किया और मैंने अपनी रिपोर्ट पूरी की। लेकिन मैं उत्पादकता के 40 मिनट खो दिया है।


यह एसिंक्रोनस बनाम तुल्यकालिक व्यवहार है

यह वही है जो हमारे प्रश्न में सभी उदाहरणों में हो रहा है। एक छवि लोड हो रहा है, डिस्क से एक फ़ाइल लोड हो रहा है, और AJAX के माध्यम से एक पृष्ठ का अनुरोध सभी धीमी गति से कार्य कर रहे हैं (आधुनिक कंप्यूटिंग के संदर्भ में)।

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

var outerScopeVar;    
var img = document.createElement('img');

// Here we register the callback function.
img.onload = function() {
    // Code within this function will be executed once the image has loaded.
    outerScopeVar = this.width;
};

// But, while the image is loading, JavaScript continues executing, and
// processes the following lines of JavaScript.
img.src = 'lolcat.png';
alert(outerScopeVar);

ऊपर दिए गए कोड में, हम जावास्क्रिप्ट को लोड करने के लिए कह रहे हैं lolcat.png, जो एक स्लो ऑपरेशन है। इस धीमे संचालन के बाद कॉलबैक फ़ंक्शन निष्पादित किया जाएगा, लेकिन इस बीच, जावास्क्रिप्ट कोड की अगली पंक्तियों को संसाधित करता रहेगा; यानी alert(outerScopeVar)

यही कारण है कि हम चेतावनी दिखाते हैं undefined; चूंकि alert()छवि को लोड किए जाने के बजाय तुरंत संसाधित किया जाता है।

अपने कोड को ठीक करने के लिए, हमें केवल कॉलबैक फ़ंक्शन मेंalert(outerScopeVar) कोड को स्थानांतरित करना होगा । इसके परिणामस्वरूप, हमें अब outerScopeVarवैश्विक चर के रूप में घोषित चर की आवश्यकता नहीं है ।

var img = document.createElement('img');

img.onload = function() {
    var localScopeVar = this.width;
    alert(localScopeVar);
};

img.src = 'lolcat.png';

आप हमेशा देखेंगे कि एक कॉलबैक एक फ़ंक्शन के रूप में निर्दिष्ट किया गया है, क्योंकि यह कुछ कोड को परिभाषित करने के लिए जावास्क्रिप्ट में एकमात्र * तरीका है, लेकिन बाद तक इसे निष्पादित नहीं करता है।

इसलिए, हमारे सभी उदाहरणों में, function() { /* Do something */ }कॉलबैक है; सभी उदाहरणों को ठीक करने के लिए, हमें केवल उस कोड को स्थानांतरित करना होगा जिसमें ऑपरेशन की प्रतिक्रिया की आवश्यकता है!

* तकनीकी रूप से आप इसका उपयोग कर सकते हैं eval(), लेकिन इस उद्देश्य के लिए eval()बुराई है


मैं अपने कॉलर को प्रतीक्षा में कैसे रखूं?

वर्तमान में आपके पास इसके समान कुछ कोड हो सकते हैं;

function getWidthOfImage(src) {
    var outerScopeVar;

    var img = document.createElement('img');
    img.onload = function() {
        outerScopeVar = this.width;
    };
    img.src = src;
    return outerScopeVar;
}

var width = getWidthOfImage('lolcat.png');
alert(width);

हालांकि, अब हम जानते हैं कि return outerScopeVarतुरंत होता है; onloadकॉलबैक फ़ंक्शन से पहले चर को अद्यतन किया गया है। यह getWidthOfImage()वापस लौटने undefinedऔर undefinedसतर्क रहने की ओर जाता है ।

इसे ठीक करने के लिए, हमें getWidthOfImage()कॉलबैक को पंजीकृत करने के लिए फ़ंक्शन को कॉल करने की अनुमति देने की आवश्यकता है , फिर उस कॉलबैक के भीतर होने वाली चौड़ाई के अलर्टिंग को स्थानांतरित करें;

function getWidthOfImage(src, cb) {     
    var img = document.createElement('img');
    img.onload = function() {
        cb(this.width);
    };
    img.src = src;
}

getWidthOfImage('lolcat.png', function (width) {
    alert(width);
});

... पहले की तरह, ध्यान दें कि हम वैश्विक चर (इस मामले में width) निकालने में सक्षम हैं ।

75 JohnnyHK Jan 21 2015 at 06:42

यहां उन लोगों के लिए अधिक संक्षिप्त जवाब दिया गया है जो कि त्वरित संदर्भ के साथ-साथ कुछ उदाहरणों का उपयोग कर रहे हैं जो वादे और async / प्रतीक्षा का उपयोग कर रहे हैं।

उस फ़ंक्शन के लिए भोले दृष्टिकोण (जो काम नहीं करता है) से शुरू करें जो एक अतुल्यकालिक विधि (इस मामले में setTimeout) को कॉल करता है और एक संदेश देता है:

function getMessage() {
  var outerScopeVar;
  setTimeout(function() {
    outerScopeVar = 'Hello asynchronous world!';
  }, 0);
  return outerScopeVar;
}
console.log(getMessage());

undefinedइस मामले में लॉग इन किया जाता है क्योंकि कॉलबैक कॉल करने और अपडेट getMessageहोने से पहले रिटर्न ।setTimeoutouterScopeVar

इसे हल करने के दो मुख्य तरीके कॉलबैक और वादों का उपयोग कर रहे हैं :

कॉलबैक

यहां परिवर्तन यह है कि getMessageएक callbackपैरामीटर को स्वीकार करता है जिसे उपलब्ध कॉल कोड में वापस परिणाम देने के लिए कहा जाएगा।

function getMessage(callback) {
  setTimeout(function() {
    callback('Hello asynchronous world!');
  }, 0);
}
getMessage(function(message) {
  console.log(message);
});

वादे

वादे एक विकल्प प्रदान करते हैं जो कॉलबैक की तुलना में अधिक लचीला होता है क्योंकि वे स्वाभाविक रूप से कई async संचालन समन्वय करने के लिए संयुक्त हो सकते हैं। एक वादा / ए + मानक कार्यान्वयन मूल रूप से नोड.जेएस (0.12+) और कई वर्तमान ब्राउज़रों में प्रदान किया गया है, लेकिन ब्लूबर्ड और क्यू जैसी पुस्तकालयों में भी लागू किया गया है ।

function getMessage() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('Hello asynchronous world!');
    }, 0);
  });
}

getMessage().then(function(message) {
  console.log(message);  
});

jQuery के डिफ्रेड्स

jQuery अपनी Deferreds के साथ वादों के समान कार्यक्षमता प्रदान करता है।

function getMessage() {
  var deferred = $.Deferred();
  setTimeout(function() {
    deferred.resolve('Hello asynchronous world!');
  }, 0);
  return deferred.promise();
}

getMessage().done(function(message) {
  console.log(message);  
});

async / इंतजार

आपकी जावास्क्रिप्ट पर्यावरण के लिए समर्थन शामिल हैं asyncऔर await(Node.js तरह 7.6+), तो आप के भीतर तुल्यकालिक वादों का उपयोग कर सकते asyncकार्य:

function getMessage () {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('Hello asynchronous world!');
        }, 0);
    });
}

async function main() {
    let message = await getMessage();
    console.log(message);
}

main();
58 JohannesFahrenkrug Dec 08 2015 at 23:48

स्पष्ट बताने के लिए, कप का प्रतिनिधित्व करता है outerScopeVar

अतुल्यकालिक कार्यों की तरह ...

14 Teja Feb 26 2016 at 10:59

अन्य उत्तर बहुत अच्छे हैं और मैं सिर्फ इस पर एक सीधा आगे जवाब देना चाहता हूं। बस jQuery अतुल्यकालिक कॉल करने के लिए सीमित है

सभी ajax कॉल (सहित $.getया $.postया $.ajax) अतुल्यकालिक कर रहे हैं।

अपने उदाहरण को देखते हुए

var outerScopeVar;  //line 1
$.post('loldog', function(response) {  //line 2
    outerScopeVar = response;
});
alert(outerScopeVar);  //line 3

कोड निष्पादन लाइन 1 से शुरू होता है, जो चर और ट्रिगर को घोषित करता है और लाइन 2 पर अतुल्यकालिक कॉल करता है, (यानी, पोस्ट अनुरोध) और यह लाइन 3 से अपने निष्पादन को जारी रखता है, इसके निष्पादन को पूरा करने के लिए पोस्ट अनुरोध का इंतजार किए बिना।

कहते हैं कि पोस्ट अनुरोध को पूरा होने में 10 सेकंड लगते हैं, outerScopeVarइच्छा का मूल्य केवल उन 10 सेकंड के बाद सेट किया जाएगा।

कठिन परीक्षा लेना,

var outerScopeVar; //line 1
$.post('loldog', function(response) {  //line 2, takes 10 seconds to complete
    outerScopeVar = response;
});
alert("Lets wait for some time here! Waiting is fun");  //line 3
alert(outerScopeVar);  //line 4

अब जब आप इसे निष्पादित करते हैं, तो आपको लाइन 3 पर अलर्ट मिलेगा। अब कुछ समय तक प्रतीक्षा करें जब तक कि आप सुनिश्चित न हो जाएं कि पोस्ट अनुरोध ने कुछ मूल्य वापस कर दिया है। फिर जब आप अलर्ट बॉक्स पर ओके पर क्लिक करते हैं, तो अगला अलर्ट अपेक्षित मूल्य प्रिंट करेगा, क्योंकि आपने इसके लिए इंतजार किया था।

वास्तविक जीवन परिदृश्य में, कोड बन जाता है,

var outerScopeVar;
$.post('loldog', function(response) {
    outerScopeVar = response;
    alert(outerScopeVar);
});

सभी कोड जो अतुल्यकालिक कॉल पर निर्भर करते हैं, उन्हें अतुल्यकालिक ब्लॉक के अंदर स्थानांतरित किया जाता है, या अतुल्यकालिक कॉल पर प्रतीक्षा करके।

11 TomSebastian Oct 27 2015 at 13:35

इन सभी स्थितियों में outerScopeVarसंशोधित या एक मूल्य असाइन किया गया है एसिंक्रोनस रूप से या बाद में किसी समय में हो रहा (इंतजार कर या किसी घटना होने के लिए सुन रहा), जिसके लिए वर्तमान निष्पादन के लिए इंतजार नहीं होगा तो इन सभी मामलों वर्तमान निष्पादन प्रवाह परिणामों मेंouterScopeVar = undefined

आइए प्रत्येक उदाहरणों पर चर्चा करें (मैंने उस हिस्से को चिह्नित किया है जिसे असिंक्रोनसली कहा जाता है या कुछ घटनाओं के होने में देरी होती है):

1।

यहां हम एक इवेंटलिस्ट को रजिस्टर करते हैं, जिसे उस विशेष घटना पर निष्पादित किया जाएगा। छवि का लोड हो रहा है। फिर अगली लाइनों के साथ वर्तमान निष्पादन जारी है img.src = 'lolcat.png';और alert(outerScopeVar);इस बीच घटना नहीं हो सकती है। यानी, फंतासी img.onloadको लोड करने के लिए , अतुलनीय रूप से संदर्भित छवि के लिए प्रतीक्षा करें। यह सभी फ़ोलोइंग उदाहरण होगा- घटना भिन्न हो सकती है।

2।

यहां टाइमआउट इवेंट भूमिका निभाता है, जो निर्दिष्ट समय के बाद हैंडलर को आमंत्रित करेगा। यहां यह है 0, लेकिन फिर भी यह एक अतुल्यकालिक घटना को पंजीकृत करता है इसे Event Queueनिष्पादन के लिए अंतिम स्थिति में जोड़ा जाएगा , जो गारंटीकृत देरी करता है।

3।

इस बार अजाक्स कॉलबैक।

4।

नोड को अतुल्यकालिक कोडिंग के राजा के रूप में माना जा सकता है। चिह्नित फ़ंक्शन को कॉलबैक हैंडलर के रूप में पंजीकृत किया जाता है जिसे निर्दिष्ट फ़ाइल पढ़ने के बाद निष्पादित किया जाएगा।

5।

स्पष्ट वादा (भविष्य में कुछ किया जाएगा) अतुल्यकालिक है। देखें कि जावास्क्रिप्ट में Deferred, Promise और Future के बीच क्या अंतर हैं?

https://www.quora.com/Whats-the-difference-between-a-promise-and-a-callback-in-Javascript