समझें कि इंजन असल में सिंक्रोनस कोड, माइक्रोटास्क और मैक्रोटास्क को कैसे शेड्यूल करता है।
इस पाठ को Kodokon में खोलेंJavaScript आपका कोड एक सिंगल थ्रेड पर चलाता है, लेकिन इवेंट लूप को ECMAScript परिभाषित नहीं करता: यह HTML स्पेसिफिकेशन है (और Node.js की तरफ libuv) जो बताता है कि यह कैसे काम करता है। इंजन वर्तमान में चल रहे कोड के लिए एक कॉल स्टैक बनाए रखता है, मैक्रोटास्क (टाइमर, I/O, इवेंट) की एक कतार और माइक्रोटास्क (Promise.prototype.then, queueMicrotask, MutationObserver) की एक कतार। स्वर्णिम नियम: प्रत्येक मैक्रोटास्क के बाद, नियंत्रण वापस सौंपे जाने से पहले माइक्रोटास्क कतार को पूरी तरह खाली किया जाता है।
console.log("script start");
setTimeout(() => console.log("timeout"), 0);
Promise.resolve()
.then(() => console.log("promise 1"))
.then(() => console.log("promise 2"));
console.log("script end");
// script start, script end,
// promise 1, promise 2, timeoutशुरुआती स्क्रिप्ट स्वयं एक मैक्रोटास्क है: जब तक यह समाप्त नहीं होती, कुछ और नहीं चलता। एक बार कॉल स्टैक खाली हो जाने पर, इंजन माइक्रोटास्क कतार को खाली करता है, जिसमें खाली करते समय जोड़े गए माइक्रोटास्क भी शामिल हैं। यह विवरण बताता है कि दो श्रृंखलाबद्ध then कॉल setTimeout(fn, 0) से पहले क्यों चलते हैं: प्रत्येक then एक और माइक्रोटास्क शेड्यूल करता है, और जब तक कतार खाली नहीं हो जाती, नियंत्रण कभी वापस नहीं सौंपा जाता।
setTimeout(() => console.log("macro 1"), 0);
setTimeout(() => console.log("macro 2"), 0);
queueMicrotask(() => {
console.log("micro 1");
queueMicrotask(() => console.log("micro 2"));
});
// micro 1, micro 2, macro 1, macro 2await कीवर्ड इसी तंत्र पर आधारित है: यह async फ़ंक्शन को निलंबित करता है, नियंत्रण को कॉलर को वापस सौंपता है, फिर पुनरारंभ को एक माइक्रोटास्क के रूप में शेड्यूल करता है। यहाँ तक कि await null भी यह निलंबन ट्रिगर करता है, क्योंकि मान को पहले से हल किए गए प्रॉमिस में लपेट दिया जाता है। इसीलिए await के बाद रखा गया कोड कभी सिंक्रोनस रूप से नहीं चलता।
async function main() {
console.log("before await");
await null;
console.log("after await");
}
main();
console.log("sync code");
// before await, sync code, after awaitC लॉग करती है, setTimeout(fn, 0) के माध्यम से A और Promise.resolve().then के माध्यम से B शेड्यूल करती है। अक्षर किस क्रम में दिखाई देते हैं?await अंदर से असल में क्या करता है?