2015-03-06 11 views
32

जैसा कि मैं समझता हूं कि एक वादा कुछ ऐसा है जो हल() या अस्वीकार कर सकता है() लेकिन मुझे यह पता लगाने के लिए आश्चर्य हुआ कि वादे में उस कोड को हल करने या अस्वीकार करने के बाद निष्पादित करना जारी है।किसी संकल्प के बाद जावास्क्रिप्ट ES6 वादा निष्पादन जारी क्यों करता है?

मुझे निकास या वापसी के एसिंक-अनुकूल संस्करण होने का संकल्प या अस्वीकार माना जाता है, जो सभी तत्काल कार्य निष्पादन को रोक देगा।

var call = function() { 
    return new Promise(function(resolve, reject) { 
     resolve(); 
     console.log("Doing more stuff, should not be visible after a resolve!"); 
    }); 
}; 

call().then(function() { 
    console.log("resolved"); 
}); 

jsbin

+5

उचित सवाल है, लेकिन फिर, जे एस सिर्फ एक के बाद एक बयान की तरह आप के लिए यह करने के लिए बता निष्पादित करता है। 'हल() 'एक जेएस कंट्रोल स्टेटमेंट नहीं है जो जादुई रूप से' रिटर्न 'का असर होगा, यह सिर्फ एक फंक्शन कॉल है, और हां, उसके बाद निष्पादन जारी है। –

+0

यह एक अच्छा सवाल है, और सभी प्रतिक्रियाओं को पढ़ने के बाद भी, मुझे सर्वोत्तम प्रथाओं के बारे में निश्चित नहीं है ... –

उत्तर

61

जावास्क्रिप्ट में "run to completion" की अवधारणा है। जब तक कोई त्रुटि फेंक नहीं जाती है, तब तक एक कार्य को return कथन तक निष्पादित किया जाता है या उसका अंत तक पहुंच जाता है। फ़ंक्शन के बाहर अन्य कोड उसमें हस्तक्षेप नहीं कर सकता है (जब तक, फिर से, एक त्रुटि फेंक दी जाती है)।

आप resolve() चाहते हैं अपने initialiser समारोह बाहर निकलने के लिए, आप return से यह पहले जोड़ें करने के लिए है:

return new Promise(function(resolve, reject) { 
    return resolve(); 
    console.log("Not doing more stuff after a return statement"); 
}); 
+0

हाय फ़ेलिक्स - मुझे लगता है कि यह कहानी का केवल एक हिस्सा है - दूसरा भाग यह है कि 'हल()' स्वयं ही एसिंक फ़ंक्शन है। जैसा कि हमने दूसरे (हटाए गए) उत्तर में देखा है, कुछ लोग मानते हैं कि 'समाधान' को कॉल करना तुरंत किसी भी कॉलबैक को चलाएगा। – Alnitak

+2

@ अलिताक 'संकल्प' स्वयं असीमित नहीं है, यह पूरी तरह से तुल्यकालिक है। हालांकि कड़ाई से ES6 एपीआई का उपयोग करना यह देखने योग्य नहीं है कि यह सिंक्रोनस या असीमित है या नहीं। – Esailija

+0

@Esailija ठीक है, शायद मैं अस्पष्ट था। कुछ लोग मानते हैं कि 'समाधान' को कॉल करने से परिणामस्वरूप किसी भी पंजीकृत कॉलबैक को तत्काल बुलाया जा सकता है ताकि वे वर्तमान कॉल स्टैक का हिस्सा हों। यह सच नहीं है, इसके बजाय यह केवल कॉलबैक कतारबद्ध करता है (और आप सही हैं, यह एसिंक नहीं है, लेकिन यह सिर्फ इसकी चीज करता है और तुरंत समाप्त हो जाता है) – Alnitak

14

कॉलबैक कि सक्रिय किया जाएगा जब आप resolve एक वादा अभी भी कर रहे हैं:

किसी के पीछे क्यों निम्न उदाहरण कभी कभी एक संकल्प कॉल के बाद console.log से पता चलता सोचा व्याख्या कर सकते हैं विनिर्देशन द्वारा अतुल्यकालिक रूप से कहा जाना आवश्यक है। यह तुल्यकालिक और असीमित क्रियाओं के मिश्रण के लिए वादे का उपयोग करते समय लगातार व्यवहार सुनिश्चित करना है।

इसलिए आप जब आह्वान resolve कॉलबैक पंक्तिबद्ध है, और समारोह निष्पादन resolve() आह्वान के बाद किसी भी कोड के साथ तुरंत जारी है।

केवल एक बार जब जेएस इवेंट लूप को वापस नियंत्रण दिया जाता है तो कॉलबैक को कतार से निकाल दिया जा सकता है और वास्तव में बुलाया जा सकता है।

+0

कॉलबैक क्यूइंग ए + चश्मा या ES6 में प्रलेखित है? – thefourtheye

+4

@thefourtheye: इवेंट लूप विनिर्देश वास्तव में [HTML5] (http://www.w3.org/TR/html5/webappapis.html#event-loops) का हिस्सा है। ES6 [** 'EnqueueJob' **] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-enqueuejob) नामक एक आंतरिक विधि को परिभाषित करता है, जिसे [**' .then द्वारा लागू किया जाता है) '**] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise.prototype.then)। –

+0

@ फ़ेलिक्सक्लिंग ओह धन्यवाद :) – thefourtheye

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