2016-04-26 14 views
19

मैं अपने आप को निम्न स्निपेट का निष्पादन आदेश समझाऊंगा जो जावास्क्रिप्ट वादे का उपयोग करता है।जावास्क्रिप्ट वादे में निष्पादन का आदेश

Promise.resolve('A') 
    .then(function(a){console.log(2, a); return 'B';}) 
    .then(function(a){ 
    Promise.resolve('C') 
     .then(function(a){console.log(7, a);}) 
     .then(function(a){console.log(8, a);}); 
    console.log(3, a); 
    return a;}) 
    .then(function(a){ 
    Promise.resolve('D') 
     .then(function(a){console.log(9, a);}) 
     .then(function(a){console.log(10, a);}); 
    console.log(4, a);}) 
    .then(function(a){ 
    console.log(5, a);}); 
console.log(1); 
setTimeout(function(){console.log(6)},0); 

परिणाम है:

1 
2 "A" 
3 "B" 
7 "C" 
4 "B" 
8 undefined 
9 "D" 
5 undefined 
10 undefined 
6 

मैं निष्पादन आदेश 1 2 3 7 ... नहीं मान 'ए', 'बी' ...

के बारे में उत्सुक हूँ मेरी समझ यह है कि अगर एक वादा हल हो जाता है तो 'ईवेंट' फ़ंक्शन ब्राउज़र ईवेंट कतार में रखा जाता है। तो मेरी उम्मीद से 1 2 3 4 था ...


@ jfriend00 धन्यवाद, धन्यवाद विस्तृत व्याख्या के लिए बहुत कुछ! यह वास्तव में काम की एक बड़ी राशि है!

+1

वचन 'वापसी' मूल्य से काम करते हैं वे जादुई नहीं हैं :) यदि आप 'फिर' से वापस नहीं आते हैं तो यह काम नहीं करेगा। यदि आप अपने कार्यों को जोड़ने के लिए 'वापसी' जोड़ते हैं तो यह आपकी अपेक्षा के अनुसार काम करेगा। इसके 100 डुप्लीकेट हैं - बस एक अच्छा इंगित करने के लिए बर्गि या जिफ्रेंड की प्रतीक्षा करेंगे। –

+0

* "मैं निष्पादन आदेश 1 2 3 7 के बारे में उत्सुक हूं ... मूल्य 'ए', 'बी' नहीं ..." * फिर प्रश्न से अपर्याप्त जानकारी और कोड हटा दें। –

+1

यदि आप स्पष्ट रूप से वादे से 'वापसी' नहीं करते हैं, तो यह असल में – Srle

उत्तर

42

टिप्पणियाँ

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

तो, आपके सभी Promise.resolve().then() हैंडलर के अंदर वादे नए वादा श्रृंखला बनाते हैं जो मूल श्रृंखला से स्वतंत्र रूप से चलते हैं। आपके पास कोई दृढ़ व्यवहार नहीं है। यह समानांतर में चार AJAX कॉल लॉन्च करने जैसा है। आप नहीं जानते कि कौन सा पहला पूरा करेगा। अब, चूंकि Promise.resolve() हैंडलर के अंदर आपके सभी कोड सिंक्रोनस होते हैं (क्योंकि यह वास्तविक दुनिया कोड नहीं है), तो आपको लगातार व्यवहार मिल सकता है, लेकिन यह वादे का डिज़ाइन बिंदु नहीं है इसलिए मैं अधिक समय नहीं व्यतीत करूंगा यह समझने की कोशिश कर रहा है कि कौन सी वादा श्रृंखला जो सिंक्रोनस कोड चलाती है केवल पहले खत्म होने जा रही है। असली दुनिया में, इससे कोई फर्क नहीं पड़ता क्योंकि अगर आदेश मायने रखता है, तो आप चीजों को मौके पर नहीं छोड़ेंगे।

सारांश

  1. सभी .then() संचालकों एसिंक्रोनस रूप से निष्पादन खत्म की वर्तमान धागा के बाद कहा जाता है (वादे/ए + कल्पना कहते हैं, जब जे एस इंजन वापस "मंच कोड" रिटर्न)। यह उन वादों के लिए भी सच है जो Promise.resolve().then(...) जैसे समकालिक रूप से हल किए गए हैं।यह प्रोग्रामिंग स्थिरता के लिए किया जाता है ताकि .then() हैंडलर को लगातार अतुल्यकालिक कहा जाता है चाहे कोई वादा तुरंत या बाद में हल हो जाए। यह कुछ समय की बग को रोकता है और कॉलिंग कोड को लगातार असीमित निष्पादन को देखने में आसान बनाता है।

  2. कोई विनिर्देश नहीं है जो setTimeout() बनाम निर्धारित .then() हैंडलर के सापेक्ष क्रम को निर्धारित करता है यदि दोनों कतारबद्ध हैं और चलाने के लिए तैयार हैं। आपके कार्यान्वयन में, लंबित .then() हैंडलर हमेशा लंबित setTimeout() से पहले चलाया जाता है, लेकिन वादा/ए + स्पेक विनिर्देश कहता है कि यह निर्धारित नहीं है। यह कहता है कि .then() हैंडलर को विभिन्न तरीकों से निर्धारित किया जा सकता है, जिनमें से कुछ setTimeout() कॉल लंबित होने से पहले चलाए जाएंगे और इनमें से कुछ setTimeout() कॉल लंबित होने के बाद चल सकते हैं। उदाहरण के लिए, वादे/ए + स्पेक .then() हैंडलर को setImmediate() के साथ निर्धारित करने की अनुमति देता है जो setTimeout() कॉल लंबित होने से पहले या setTimeout() के साथ चलाएगा जो setTimeout() कॉल लंबित होने के बाद चलाएगा। तो, आपका कोड उस आदेश पर निर्भर नहीं होना चाहिए।

  3. एकाधिक स्वतंत्र वादा श्रृंखलाओं में निष्पादन का अनुमानित आदेश नहीं है और आप किसी विशेष आदेश पर भरोसा नहीं कर सकते हैं। यह समानांतर में चार AJAX कॉलों को फायरिंग की तरह है जहां आप नहीं जानते कि कौन सा पहला पूरा करेगा।

  4. यदि निष्पादन का आदेश महत्वपूर्ण है, तो उस दौड़ को न बनाएं जो मिनट कार्यान्वयन विवरण पर निर्भर है। इसके बजाय, एक विशेष निष्पादन आदेश को मजबूर करने के लिए वादे श्रृंखलाओं को लिंक करें।

  5. आप आम तौर पर .then() हैंडलर के भीतर स्वतंत्र वादे श्रृंखला बनाना नहीं चाहते हैं जो हैंडलर से वापस नहीं आते हैं। आग के दुर्लभ मामलों को छोड़कर यह आमतौर पर एक बग होता है और त्रुटि प्रबंधन के बिना भूल जाता है।

लाइन लाइन Analsysis

तक तो, यहाँ अपने कोड के एक विश्लेषण है। मैं लाइन नंबर जोड़ा गया है और यह आसान चर्चा करने के लिए बनाने के लिए खरोज साफ:

1  Promise.resolve('A').then(function (a) { 
2   console.log(2, a); 
3   return 'B'; 
4  }).then(function (a) { 
5   Promise.resolve('C').then(function (a) { 
6    console.log(7, a); 
7   }).then(function (a) { 
8    console.log(8, a); 
9   }); 
10  console.log(3, a); 
11  return a; 
12 }).then(function (a) { 
13  Promise.resolve('D').then(function (a) { 
14   console.log(9, a); 
15  }).then(function (a) { 
16   console.log(10, a); 
17  }); 
18  console.log(4, a); 
19 }).then(function (a) { 
20  console.log(5, a); 
21 }); 
22 
23 console.log(1); 
24  
25 setTimeout(function() { 
26  console.log(6) 
27 }, 0); 

पंक्ति 1 एक वादा श्रृंखला शुरू होता है और इसे करने के लिए एक .then() हैंडलर संलग्न। चूंकि Promise.resolve() तुरंत हल हो जाता है, इसलिए वादा पुस्तकालय जावास्क्रिप्ट खत्म होने के इस धागे के बाद चलाने के लिए पहले .then() हैंडलर शेड्यूल करेगा। वादे/ए + संगत वादा पुस्तकालयों में, सभी .then() हैंडलर निष्पादन के वर्तमान धागे के बाद असीमित रूप से कहा जाता है और जब जेएस घटना लूप पर वापस जाता है। इसका मतलब यह है कि इस धागे में कोई अन्य सिंक्रोनस कोड जैसे कि console.log(1) अगले दिखाई देगा जो आप देखते हैं।

अन्य सभी .then() शीर्ष स्तर पर संचालकों (लाइनों 4, 12, 19) श्रृंखला पहले एक के बाद के बाद ही पहले एक अपनी बारी हो जाता है चलेंगे। वे अनिवार्य रूप से इस बिंदु पर कतारबद्ध हैं।

चूंकि setTimeout() निष्पादन के प्रारंभिक धागे में भी है, यह चलाया जाता है और इस प्रकार टाइमर निर्धारित होता है।

यह तुल्यकालिक निष्पादन का अंत है। अब, जेएस इंजन घटना कतार में निर्धारित चीजें चलाना शुरू कर देता है।

जहां तक ​​मुझे पता है, वहां कोई गारंटी नहीं है जो पहले setTimeout(fn, 0) या .then() हैंडलर है जो दोनों निष्पादन के इस धागे के ठीक बाद चलाने के लिए निर्धारित हैं। .then() हैंडलर को "माइक्रो-वर्क्स" माना जाता है, इसलिए यह मुझे आश्चर्य नहीं करता कि वे setTimeout() से पहले पहले भागते हैं। लेकिन, अगर आपको किसी विशेष आदेश की आवश्यकता है, तो आपको कोड लिखना चाहिए जो इस कार्यान्वयन के विस्तार पर निर्भर रहने के बजाय आदेश की गारंटी देता है।

वैसे भी, .then() हैंडलर लाइन 1 पर परिभाषित है। इस प्रकार आप उस console.log(2, a) से 2 "A" आउटपुट देखते हैं।

इसके बाद, के बाद से पिछले .then() हैंडलर एक सादे मान दिया, उस वादे का समाधान तो .then() हैंडलर लाइन 4 रन पर परिभाषित माना जाता है। यहां वह जगह है जहां आप एक और स्वतंत्र वादा श्रृंखला बना रहे हैं और आमतौर पर एक बग है जो एक व्यवहार शुरू कर रहे हैं।

रेखा 5, एक नई वादा श्रृंखला बनाता है। यह प्रारंभिक वादा को हल करता है और उसके बाद निष्पादन के वर्तमान धागे को चलाने के लिए दो .then() हैंडलर शेड्यूल करता है। निष्पादन के उस वर्तमान धागे में console.log(3, a) लाइन 10 पर है इसलिए आप इसे अगले देखते हैं। फिर, निष्पादन का यह धागा खत्म हो जाता है और यह देखने के लिए शेड्यूलर पर वापस जाता है कि आगे क्या चलना है।

अब हमारे पास कतार में कई .then() हैंडलर अगले भागने की प्रतीक्षा कर रहे हैं। वहाँ एक हम सिर्फ लाइन 5 पर निर्धारित है और वहाँ लाइन 12 उच्च स्तर श्रृंखला में अगले एक है आप लाइन 5 पर इस किया था, तो:

return Promise.resolve.then(...) 

तो आप इन वादों को एक साथ जोड़ा और है | वे अनुक्रम में समन्वयित किया जाएगा। लेकिन, वादे मूल्य वापस नहीं लौटने के बाद, आपने एक पूरी नई वादा श्रृंखला शुरू की जो बाहरी, उच्च स्तर के वादे के साथ समन्वयित नहीं है। आपके विशेष मामले में, वादा शेड्यूलर अगले गहराई से घोंसला वाले .then() हैंडलर को चलाने का निर्णय लेता है। मैं ईमानदारी से नहीं जानता कि यह विनिर्देश द्वारा, सम्मेलन द्वारा या केवल एक वादे इंजन बनाम एक कार्यान्वयन विवरण है। मैं कहूंगा कि अगर आदेश आपके लिए महत्वपूर्ण है, तो आपको पहले चलाने के लिए दौड़ जीतने पर भरोसा करने के बजाय किसी विशिष्ट क्रम में वादे को जोड़कर एक आदेश को मजबूर करना चाहिए।

वैसे भी, आपके मामले में, यह एक समय निर्धारण दौड़ है और इंजन आप चल रहे हैं भीतरी .then() हैंडलर कि लाइन 5 पर अगले परिभाषित किया है भागने का फैसला किया है और इस तरह आप देख 7 "C"लाइन 6 पर निर्दिष्ट। फिर यह कुछ भी नहीं देता है इसलिए इस वादे का हल मूल्य undefined बन जाता है।

शेड्यूलर में वापस, यह .then() हैंडलर लाइन 12 पर चलाता है। यह फिर से .then() हैंडलर और लाइन 7 पर एक दौड़ है जो दौड़ने का इंतजार कर रहा है। मुझे नहीं पता कि यह एक दूसरे के ऊपर क्यों चुनता है यह कहने के अलावा कि यह अनिश्चित हो सकता है या प्रति वादे इंजन में भिन्न हो सकता है क्योंकि आदेश कोड द्वारा निर्दिष्ट नहीं है। किसी भी मामले में, .then() हैंडलर लाइन 12 चलाने के लिए शुरू होता है। यह फिर से एक नई स्वतंत्र या अनसंक्रनाइज़ वादा श्रृंखला लाइन पिछले बनाता है। यह .then() हैंडलर को फिर से शेड्यूल करता है और फिर आपको .then() हैंडलर में सिंक्रोनस कोड से 4 "B" मिलता है। सभी सिंक्रोनस कोड उस हैंडलर में अब किया जाता है, इसलिए यह अगले कार्य के लिए शेड्यूलर पर वापस जाता है।

अनुसूचक में वापस, यह लाइन 7 पर .then() हैंडलर भागने का फैसला किया है और आप 8 undefined मिलता है। वादा undefined है क्योंकि पिछले .then() उस श्रृंखला में हैंडलर कुछ भी वापस नहीं आया था, इस प्रकार इसका वापसी मूल्य undefined था, इस प्रकार वह उस बिंदु पर वादे श्रृंखला का हल मूल्य है।

इस बिंदु पर, उत्पादन अब तक है:

1 
2 "A" 
3 "B" 
7 "C" 
4 "B" 
8 undefined 

फिर, सभी तुल्यकालिक कोड किया जाता है तो यह फिर से नियोजक को वापस चला जाता है और यह .then() हैंडलर लाइन 13 पर परिभाषित भागने का फैसला किया । यह चलता है और आपको आउटपुट 9 "D" मिलता है और फिर यह शेड्यूलर पर फिर से जाता है।

पहले नेस्ट Promise.resolve() श्रृंखला के अनुरूप, अनुसूची अगले बाहरी .then() हैंडलर लाइन 19 पर परिभाषित चलाने का निर्णय लेता। यह चलता है और आपको आउटपुट 5 undefined मिलता है। यह फिर से undefined है क्योंकि पिछले .then() उस श्रृंखला में हैंडलर ने कोई मूल्य नहीं लौटाया, इस प्रकार वादे का हल मूल्य undefined था।

इस बिंदु के रूप में, उत्पादन अब तक है:

1 
2 "A" 
3 "B" 
7 "C" 
4 "B" 
8 undefined 
9 "D" 
5 undefined 

इस बिंदु पर, केवल एक .then() हैंडलर यह इतना चलाने के लिए अनुसूचित लाइन 15 पर परिभाषित एक रन है और आपको मिल आउटपुट 10 undefined अगला।

फिर, अंत में, setTimeout() चलाने के लिए हो जाता है और अंतिम आउटपुट है:

1 
2 "A" 
3 "B" 
7 "C" 
4 "B" 
8 undefined 
9 "D" 
5 undefined 
10 undefined 
6 

एक बिल्कुल इस में काम कर भविष्यवाणी करने के लिए प्रयास करने के लिए थे, तो वहाँ दो मुख्य सवाल होगा।

  1. कैसे .then() संचालकों प्राथमिकता के आधार पर बनाम setTimeout() कॉल कि भी लंबित हैं लंबित हैं।

  2. वादा इंजन कितने .then() हैंडलर को प्राथमिकता देने का निर्णय लेता है जो सभी दौड़ने की प्रतीक्षा कर रहे हैं। इस कोड के साथ अपने परिणामों के अनुसार यह फीफो नहीं है।

पहला सवाल के लिए, मैं अगर यह विनिर्देश या वादा इंजन/जे एस इंजन में सिर्फ एक कार्यान्वयन विकल्प यहाँ प्रति है पता नहीं है, लेकिन कार्यान्वयन आप को सूचना दी से पहले सभी लंबित .then() संचालकों को प्राथमिकता देने के लिए प्रकट होता है कोई भी setTimeout() कॉल। आपका मामला एक अजीब बात है क्योंकि आपके पास .then() हैंडलर निर्दिष्ट करने के अलावा कोई वास्तविक एसिंक एपीआई कॉल नहीं है। यदि आपके पास कोई एसिंक ऑपरेशन था जो वास्तव में इस वादे श्रृंखला की शुरुआत में निष्पादित करने के लिए कोई वास्तविक समय लेता था, तो setTimeout() असली एसिंक ऑपरेशन पर .then() हैंडलर से पहले निष्पादित करेगा क्योंकि असली एसिंक ऑपरेशन निष्पादित करने के लिए वास्तविक समय लेता है। तो, यह एक संक्षिप्त उदाहरण है और वास्तविक कोड के लिए सामान्य डिजाइन केस नहीं है।

दूसरे प्रश्न के लिए, मैंने कुछ चर्चा देखी है जो चर्चा करता है कि .then() घोंसले के विभिन्न स्तरों पर हैंडलर को प्राथमिकता दी जानी चाहिए। मुझे नहीं पता कि उस चर्चा को किसी विनिर्देश में हल किया गया था या नहीं। मैं इस तरह से कोड करना पसंद करता हूं कि विस्तार का स्तर मुझसे कोई फर्क नहीं पड़ता। अगर मुझे अपने एसिंक ऑपरेशंस के आदेश की परवाह है, तो मैं आदेश को नियंत्रित करने के लिए अपने वादे श्रृंखलाओं को जोड़ता हूं और कार्यान्वयन के इस स्तर के विस्तार से मुझे किसी भी तरह प्रभावित नहीं होता है। अगर मुझे आदेश की परवाह नहीं है, तो मुझे इस आदेश की परवाह नहीं है कि फिर से कार्यान्वयन के स्तर का स्तर मुझे प्रभावित नहीं करता है। यहां तक ​​कि अगर यह कुछ विनिर्देशों में था, तो ऐसा लगता है कि कई प्रकार के कार्यान्वयन (विभिन्न ब्राउज़रों, विभिन्न वादे इंजन) पर भरोसा नहीं किया जाना चाहिए, जब तक कि आप इसे हर जगह परीक्षण नहीं करते थे, जिसे आप चलाने जा रहे थे। इसलिए, जब आप अनसंक्रनाइज़ वादे श्रृंखला प्राप्त करते हैं तो मैं निष्पादन के विशिष्ट क्रम पर भरोसा नहीं करने की अनुशंसा करता हूं।


तुम बस की तरह इस (भीतरी वादों लौटने तो वे माता-पिता श्रृंखला में जुड़े हुए हैं) अपने सभी वादे जंजीरों को जोड़ने के द्वारा आदेश 100% नियत कर सकता है:

Promise.resolve('A').then(function (a) { 
    console.log(2, a); 
    return 'B'; 
}).then(function (a) { 
    var p = Promise.resolve('C').then(function (a) { 
     console.log(7, a); 
    }).then(function (a) { 
     console.log(8, a); 
    }); 
    console.log(3, a); 
    // return this promise to chain to the parent promise 
    return p; 
}).then(function (a) { 
    var p = Promise.resolve('D').then(function (a) { 
     console.log(9, a); 
    }).then(function (a) { 
     console.log(10, a); 
    }); 
    console.log(4, a); 
    // return this promise to chain to the parent promise 
    return p; 
}).then(function (a) { 
    console.log(5, a); 
}); 

console.log(1); 

setTimeout(function() { 
    console.log(6) 
}, 0); 

यह निम्न उत्पादन देता है क्रोम में:

1 
2 "A" 
3 "B" 
7 "C" 
8 undefined 
4 undefined 
9 "D" 
10 undefined 
5 undefined 
6 

और, क्योंकि वादे को सभी एक साथ बंधे हुए हैं, वादा आदेश सभी कोड द्वारा परिभाषित किया गया है। एक कार्यान्वयन विस्तार के रूप में छोड़ी गई एकमात्र चीज setTimeout() का समय है, जैसा कि आपके उदाहरण में, .then() हैंडलर लंबित होने के बाद अंतिम बार आता है।

संपादित करें:

Promises/A+ specification की परीक्षा पर, हम इस लगता है:

2.2.4 onFulfilled या onRejected तक निष्पादन संदर्भ ढेर केवल मंच कोड शामिल नहीं कहा जाना चाहिए। [3.1]।

....

3.1 यहाँ "मंच कोड" इंजन, पर्यावरण, और वादा कार्यान्वयन कोड का मतलब है। प्रैक्टिस में, यह आवश्यकता सुनिश्चित करती है कि पर पूर्ण और ऑनरजेक्टेड एसिंक्रोनिक रूप से निष्पादित करें, घटना लूप टर्न जिसमें बाद में कहा जाता है, और एक ताजा ढेर के साथ। यह या तो "मैक्रो-टास्क" तंत्र जैसे सेटटाइमआउट या सेट इमीडिएट, या "माइक्रो-टास्क" तंत्र जैसे उत्परिवर्तन ऑब्सर्वर या process.nextTick के साथ लागू किया जा सकता है। चूंकि वादा कार्यान्वयन को प्लेटफ़ॉर्म कोड माना जाता है, इसमें स्वयं को कार्य-शेड्यूलिंग कतार या "ट्रैम्पोलिन" हो सकता है जिसमें हैंडलर कहलाए जाते हैं।

यह कहना है कि .then() संचालकों मंच कोड को कॉल स्टैक रिटर्न के बाद एसिंक्रोनस रूप से निष्पादित करना होगा, लेकिन कार्यान्वयन कैसे वास्तव में ऐसा करने के लिए करने के लिए पूरी तरह से छोड़ देता है कि क्या यह setTimeout() या सूक्ष्म कार्य की तरह की तरह एक वृहद कार्य के साथ किया जाता है process.nextTick()। तो, इस विनिर्देश के अनुसार, यह निर्धारित नहीं है और इस पर भरोसा नहीं किया जाना चाहिए।

मुझे ईएस 6 विनिर्देश में setTimeout() के संबंध में मैक्रो-वर्क्स, माइक्रो-वर्क या वचन .then() हैंडलर के बारे में कोई जानकारी नहीं मिली है।यह शायद आश्चर्यजनक नहीं है क्योंकि setTimeout() स्वयं ईएस 6 विनिर्देश का हिस्सा नहीं है (यह एक मेजबान पर्यावरण समारोह है, न कि भाषा सुविधा है)।

मुझे इसे वापस करने के लिए कोई विशिष्टता नहीं मिली है, लेकिन इस प्रश्न के उत्तर Difference between microtask and macrotask within an event loop context बताते हैं कि मैक्रो-वर्क्स और माइक्रो-वर्क वाले ब्राउज़र में चीजें कैसे काम करती हैं।

एफवाईआई, यदि आप सूक्ष्म कार्यों और मैक्रो-कार्यों पर अधिक जानकारी चाहते हैं, तो यहां विषय पर एक दिलचस्प संदर्भ आलेख है: Tasks, microtasks, queues and schedules

+0

[वचन/ए + विनिर्देश] (https://promisesaplus.com/) से लंबित '.then() 'हैंडलर बनाम' setTimeout()' के समय के बारे में जानकारी जोड़ा गया। – jfriend00

+1

डाउनवोट क्यों? मैंने यह समझाते हुए काम किया कि यह सब कैसे काम करता है। कम से कम आप यह समझा सकते हैं कि आपको क्यों लगता है कि यह एक डाउनवोट का हकदार है। अगर कुछ गलत है और आप बता सकते हैं कि, मुझे इसे सही करने में खुशी होगी। – jfriend00

+0

"जहां तक ​​मुझे पता है, कोई गारंटी नहीं है जो पहले आती है ...", यह पूरी तरह से वादे के कार्यान्वयन पर निर्भर करता है। 'सेटटाइमआउट' में वास्तव में न्यूनतम टाइमआउट देरी होती है ('15ms' आईआईआरसी की तरह कुछ) लेकिन वादा * *' setImmediate' का उपयोग कर सकता है, जिसे निश्चित रूप से एक ही समय में टाइमर सेट से पहले जेएस इवेंट लूप में जोड़ा जाएगा। वादा कार्यान्वयन अक्सर 'सेटटाइमआउट (एफएन, 0)' का उपयोग करते हैं, जो उसके क्रम में समाप्त हो जाएगा कि उनके न्यूनतम टाइमर समाप्त हो जाएंगे, जो क्रम में होते हैं। – zzzzBov

1

ब्राउज़र के जावास्क्रिप्ट इंजन में "ईवेंट लूप" कहा जाता है। एक समय में जावास्क्रिप्ट कोड का केवल एक धागा चल रहा है। जब कोई बटन क्लिक किया जाता है या AJAX अनुरोध या कुछ और एसिंक्रोनस पूर्ण होता है, तो ईवेंट लूप में एक नया ईवेंट रखा जाता है। ब्राउज़र इन घटनाओं को एक समय में निष्पादित करता है।

आप यहां क्या देख रहे हैं यह है कि आप कोड को असीमित रूप से निष्पादित करते हैं। जब एसिंक्रोनस कोड पूर्ण होता है, तो यह ईवेंट लूप में एक उचित ईवेंट जोड़ता है। घटनाओं को किस क्रम में जोड़ा जाता है इस पर निर्भर करता है कि प्रत्येक एसिंक्रोनस ऑपरेशन कब तक पूरा हो जाता है।

इसका मतलब है कि आप क्या आदेश अनुरोधों में पूरा हो जाएगा पर कोई नियंत्रण नहीं है जहाँ आप AJAX की तरह कुछ का उपयोग कर रहे हैं तो अपने वादे भिन्न क्रम में हर बार निष्पादित कर सकते हैं।

+1

वापस लौटाएगा, असल में, अधिकांश ब्राउज़रों में, '।' कॉलबैक एक माइक्रोट्रैक कतार पर निष्पादित होता है जो वर्तमान रन-टू-एंड के अंत में खाली होता है। मुख्य घटना लूप बारी से पहले, पूरा हो रहा है। – jib

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