कार्यक्रम - 1

new Promise(resolve => {
        resolve('1');
        Promise.resolve().then(() => console.log('2'));
    }).then(data => {
        console.log(data);
    }); // output 2 1

कार्यक्रम -2

new Promise(resolve => {
        Promise.resolve().then(() => {
            resolve('1');
            Promise.resolve().then(() => console.log('2'));
        });
    }).then(data => {
        console.log(data);
    }); // output 1 2

मैं वास्तव में दोनों कार्यक्रमों के आउटपुट से भ्रमित हूं। क्या कोई मुझे बता सकता है कि निष्पादन धागा यहां कैसे काम करता है?

-2
Rohit Goyal 29 मार्च 2020, 20:49
1
I am really confused with the output of both the programs. और क्यों? आपको किस आउटपुट की उम्मीद थी और क्यों?
 – 
t.niese
29 मार्च 2020, 21:01
उह, यहां आपको जो समझने की आवश्यकता है वह यह है कि दो लॉग बस असंबंधित हैं, और आपको उनके बीच किसी विशेष क्रम की अपेक्षा नहीं करनी चाहिए। यदि आपको एक की आवश्यकता है, तो एक उचित वादा श्रृंखला लिखें।
 – 
Bergi
29 मार्च 2020, 21:42
.then(func) में फ़ंक्शन Promise के हल होने के बाद निष्पादित होता है, इसे हल तर्क पास करता है।
 – 
StackSlave
30 मार्च 2020, 07:47

2 जवाब

यह समझना कठिन है कि resolve return की तरह काम नहीं करता। Promises बनाना वास्तव में एक नया async संदर्भ बनाता है। Promise के पहले फ़ंक्शन के अंदर सब कुछ समकालिक रूप से निष्पादित किया जाता है। फिर .then() विधियों को समकालिक या अतुल्यकालिक रूप से हल किए गए मानों के साथ बुलाया जाता है।

पहले उदाहरण में, आप '1' को हल करते हैं, लेकिन फिर आप Promise.resolve() के साथ एक नया Promise बनाते हैं और आप तुरंत .then() को कॉल करते हैं। चूंकि नया Promise पहले वाले के अंदर है, इसलिए सब कुछ सिंक्रोनस रूप से कहा जाता है।

new Promise(resolve => {
        resolve('1'); // Will be accessed in the .then() after then end of the callback
        Promise.resolve().then(() => log('2')); // called before the end of the function 
                                               // because the context is not yet created
    }).then(data => {
        log(data);
    }); // output 2 1

दूसरा उदाहरण बहुत कठिन है। आप वास्तव में पहले Promise के अंदर एक Promise बनाते हैं और तुरंत resolve को कॉल करते हैं। निष्पादन का क्रम होगा:

  • प्रारंभिक कॉलबैक में सबसे पहले सब कुछ
  • उसके बाद, resolve से .then की तरह eventListeners बनाएं
  • जब एक resolve को कॉल किया जाता है, तो .then में कॉलबैक निष्पादित करें

नेस्टेड promise के प्रारंभिक कार्य में कुछ भी नहीं है। तो यह सीधे then पर जाता है। .then() प्रारंभिक resolve() को कॉल करता है। यहां, eventListener का प्रकार बनाया गया है, इसलिए हम प्रारंभिक कॉलबैक पर जाते हैं। फिर हम वापस जाते हैं और बाकी फ़ंक्शन को निष्पादित करते हैं।

new Promise(resolve => {
        // Because we call resolve right away, the context of the original promise
        // is created
        Promise.resolve().then(() => {
            resolve('1'); // Calling resolve jumps us to the .then
            Promise.resolve().then(() => log('2')); // We execute after.then
        });
    }).then(data => {
        log(data);
    }); // output 1 2

अगर आपने .resolve() को हटा दिया है, तो यह पहले वाले की तरह काम करेगा:

new Promise(resolve => {
        new Promise(() => {
            resolve('1');
            Promise.resolve().then(() => log('2'));
        });
    }).then(data => {
        log(data);
    }); // output 2 1
-1
Alexandre Senges 29 मार्च 2020, 21:29
2
"चूंकि नया वादा पहले वाले के अंदर है, सब कुछ समकालिक रूप से कहा जाता है।" - नहीं। log('2') अतुल्यकालिक भी है।
 – 
Bergi
29 मार्च 2020, 21:42
मेरा मतलब यह है कि आपने अभी तक पहले वादे के लिए संदर्भ नहीं बनाया है क्योंकि आपने प्रारंभिक कार्य का दायरा नहीं छोड़ा है। वास्तव में क्या हो रहा है कि resolve('1') के पास अभी तक कोई श्रोता नहीं है, इसलिए ईवेंट लूप में कोई संबद्ध ईवेंट नहीं है। Promise.resolve().then(() => log('2')); लूप में किसी ईवेंट को तुरंत पुश और उपभोग करता है। पहले फ़ंक्शन का दायरा छोड़ते समय, आप श्रोता बनाते हैं और तुरंत resolve में मान के साथ इसका उपभोग करते हैं
 – 
Alexandre Senges
29 मार्च 2020, 21:49
आपको सराहना करनी होगी कि व्याख्या करना कितना कठिन है
 – 
Alexandre Senges
29 मार्च 2020, 21:52
"किसी ईवेंट को तुरंत लूप में धकेलता और उसका उपभोग करता है" - ठीक ऐसा ही नहीं हो रहा है। यह तुरंत कॉलबैक शेड्यूल करता है, हां, लेकिन यह वास्तव में new Promise निष्पादक के छोड़े जाने से पहले इसे निष्पादित नहीं करता है।
 – 
Bergi
29 मार्च 2020, 21:52
साथ ही, "संदर्भ" यहां सही शब्द की तरह नहीं लगता है, शायद आवश्यकता से अधिक भ्रम पैदा कर रहा है। और "कॉलिंग रिजॉल्यूशन हमें .then पर ले जाता है" बिल्कुल गलत है।
 – 
Bergi
29 मार्च 2020, 21:53

अंतर इस संदर्भ में है कि वादा को हल करते समय इवेंट लूप होता है (resolve(1))।

JS में कोड निष्पादित करने वाली 2 कतारें हैं:

  • माइक्रोटास्क क्यू
  • मैक्रोटास्क क्यू

जेएस एक माइक्रोटास्क निष्पादित करता है और फिर मैक्रोटास्क क्यू (यदि कोई हो) से सभी कार्यों को चलाता है

executor (वादा(...)) से एक वादे को हल करते समय आप मैक्रोटास्क Q के अंदर चल रहे हैं। एक वादा कॉलबैक के अंदर से निष्पादित कोड माइक्रोटास्क< पर निष्पादित किया जाता है /मजबूत> क्यू.

इस मामले में जो अंतर मायने रखता है वह यह है कि माइक्रोटास्क क्यू के अंदर से चलते समय यदि आप अन्य माइक्रोटास्क जोड़ते हैं (वादा कॉलबैक माइक्रोटास्क होते हैं) तो वे वर्तमान क्यू में जुड़ जाते हैं और इस क्यू रन के दौरान संसाधित हो जाते हैं।

यही होता है अगर नंबर 2 में, आप एक माइक्रोटास्क क्यू के अंदर से वादे को हल कर रहे हैं, यह शीर्ष स्तर Promise को हल करता है और .then(data => { log(data); }); को वर्तमान माइक्रोटास्क क्यू। तो इस रन में कॉलबैक निष्पादित हो जाएगा। दूसरी ओर, नेस्टेड प्रॉमिस Promise.resolve() के हैंडलर्स को अभी निष्पादित नहीं किया जाता है, क्योंकि हैंडलर्स को हमेशा async कहा जाता है।

नोट: निष्पादन को अवरुद्ध करते हुए, माइक्रोटास्क क्यू के अंदर से माइक्रोटास्क एड इनफिनिटम जोड़ना संभव है।

-1
Radu Diță 30 मार्च 2020, 18:58