ജാവാസ്ക്രിപ്റ്റ് ഇവന്റ് ലൂപ്പിന്റെ രഹസ്യങ്ങൾ മനസ്സിലാക്കുക, ടാസ്ക് ക്യൂ മുൻഗണനയും മൈക്രോടാസ്ക് ഷെഡ്യൂളിംഗും പഠിക്കുക. ഓരോ ആഗോള ഡെവലപ്പർക്കും ഇത് അത്യാവശ്യമായ അറിവാണ്.
ജാവാസ്ക്രിപ്റ്റ് ഇവന്റ് ലൂപ്പ്: ആഗോള ഡെവലപ്പർമാർക്കായി ടാസ്ക് ക്യൂ മുൻഗണനയും മൈക്രോടാസ്ക് ഷെഡ്യൂളിംഗും
വെബ് ഡെവലപ്മെന്റിന്റെയും സെർവർ സൈഡ് ആപ്ലിക്കേഷനുകളുടെയും ചലനാത്മക ലോകത്ത്, ജാവാസ്ക്രിപ്റ്റ് കോഡ് എങ്ങനെ എക്സിക്യൂട്ട് ചെയ്യുന്നു എന്ന് മനസ്സിലാക്കേണ്ടത് വളരെ പ്രധാനമാണ്. ലോകമെമ്പാടുമുള്ള ഡെവലപ്പർമാർക്ക്, ജാവാസ്ക്രിപ്റ്റ് ഇവന്റ് ലൂപ്പിലേക്ക് ആഴത്തിൽ ഇറങ്ങിച്ചെല്ലുന്നത് പ്രയോജനകരം മാത്രമല്ല, ഉയർന്ന പ്രകടനശേഷിയുള്ളതും പ്രതികരണശേഷിയുള്ളതും പ്രവചിക്കാവുന്നതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിന് അത്യാവശ്യമാണ്. ഈ പോസ്റ്റ് ഇവന്റ് ലൂപ്പിനെക്കുറിച്ചുള്ള സംശയങ്ങൾ ദൂരീകരിക്കും, ടാസ്ക് ക്യൂ മുൻഗണന, മൈക്രോടാസ്ക് ഷെഡ്യൂളിംഗ് തുടങ്ങിയ നിർണ്ണായക ആശയങ്ങളിൽ ശ്രദ്ധ കേന്ദ്രീകരിച്ച്, വൈവിധ്യമാർന്ന അന്താരാഷ്ട്ര പ്രേക്ഷകർക്ക് പ്രവർത്തനക്ഷമമായ ഉൾക്കാഴ്ചകൾ നൽകും.
അടിസ്ഥാനം: ജാവാസ്ക്രിപ്റ്റ് കോഡ് എങ്ങനെ പ്രവർത്തിക്കുന്നു
ഇവന്റ് ലൂപ്പിന്റെ സങ്കീർണ്ണതകളിലേക്ക് കടക്കുന്നതിന് മുൻപ്, ജാവാസ്ക്രിപ്റ്റിന്റെ അടിസ്ഥാന എക്സിക്യൂഷൻ മോഡൽ മനസ്സിലാക്കേണ്ടത് അത്യാവശ്യമാണ്. പരമ്പരാഗതമായി, ജാവാസ്ക്രിപ്റ്റ് ഒരു സിംഗിൾ-ത്രെഡഡ് ഭാഷയാണ്. ഇതിനർത്ഥം, ഒരു സമയം ഒരു പ്രവർത്തനം മാത്രമേ ഇതിന് ചെയ്യാൻ കഴിയൂ എന്നാണ്. എന്നിരുന്നാലും, ആധുനിക ജാവാസ്ക്രിപ്റ്റിന്റെ മാന്ത്രികത, പ്രധാന ത്രെഡിനെ തടസ്സപ്പെടുത്താതെ അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യാനുള്ള അതിന്റെ കഴിവിലാണ്, ഇത് ആപ്ലിക്കേഷനുകൾക്ക് ഉയർന്ന പ്രതികരണശേഷി നൽകുന്നു.
ഇത് ഇനിപ്പറയുന്നവയുടെ സംയോജനത്തിലൂടെയാണ് നേടുന്നത്:
- കോൾ സ്റ്റാക്ക് (The Call Stack): ഇവിടെയാണ് ഫംഗ്ഷൻ കോളുകൾ കൈകാര്യം ചെയ്യുന്നത്. ഒരു ഫംഗ്ഷൻ വിളിക്കുമ്പോൾ, അത് സ്റ്റാക്കിന്റെ മുകളിൽ ചേർക്കപ്പെടുന്നു. ഒരു ഫംഗ്ഷൻ പൂർത്തിയാകുമ്പോൾ, അത് മുകളിൽ നിന്ന് നീക്കംചെയ്യുന്നു. സിൻക്രണസ് കോഡ് എക്സിക്യൂഷൻ ഇവിടെയാണ് നടക്കുന്നത്.
- വെബ് എപിഐകൾ (ബ്രൗസറുകളിൽ) അല്ലെങ്കിൽ സി++ എപിഐകൾ (നോഡ്.ജെഎസ്-ൽ): ജാവാസ്ക്രിപ്റ്റ് പ്രവർത്തിക്കുന്ന എൻവയോൺമെന്റ് നൽകുന്ന പ്രവർത്തനങ്ങളാണിത് (ഉദാഹരണത്തിന്,
setTimeout, DOM ഇവന്റുകൾ,fetch). ഒരു അസിൻക്രണസ് പ്രവർത്തനം നേരിടുമ്പോൾ, അത് ഈ എപിഐകൾക്ക് കൈമാറുന്നു. - കോൾബാക്ക് ക്യൂ (അല്ലെങ്കിൽ ടാസ്ക് ക്യൂ): ഒരു വെബ് എപിഐ ആരംഭിച്ച അസിൻക്രണസ് പ്രവർത്തനം പൂർത്തിയാകുമ്പോൾ (ഉദാഹരണത്തിന്, ഒരു ടൈമർ അവസാനിക്കുമ്പോൾ, ഒരു നെറ്റ്വർക്ക് അഭ്യർത്ഥന പൂർത്തിയാകുമ്പോൾ), അതിന്റെ അനുബന്ധ കോൾബാക്ക് ഫംഗ്ഷൻ കോൾബാക്ക് ക്യൂവിൽ സ്ഥാപിക്കപ്പെടുന്നു.
- ഇവന്റ് ലൂപ്പ് (The Event Loop): ഇതാണ് ഓർക്കസ്ട്രേറ്റർ. ഇത് കോൾ സ്റ്റാക്കും കോൾബാക്ക് ക്യൂവും തുടർച്ചയായി നിരീക്ഷിക്കുന്നു. കോൾ സ്റ്റാക്ക് ശൂന്യമാകുമ്പോൾ, അത് കോൾബാക്ക് ക്യൂവിൽ നിന്ന് ആദ്യത്തെ കോൾബാക്ക് എടുത്ത് എക്സിക്യൂഷനായി കോൾ സ്റ്റാക്കിലേക്ക് പുഷ് ചെയ്യുന്നു.
setTimeout പോലുള്ള ലളിതമായ അസിൻക്രണസ് ടാസ്ക്കുകൾ എങ്ങനെ കൈകാര്യം ചെയ്യുന്നുവെന്ന് ഈ അടിസ്ഥാന മാതൃക വിശദീകരിക്കുന്നു. എന്നിരുന്നാലും, പ്രോമിസുകൾ, async/await, മറ്റ് ആധുനിക സവിശേഷതകൾ എന്നിവയുടെ ആവിർഭാവം മൈക്രോടാസ്ക്കുകൾ ഉൾപ്പെടുന്ന കൂടുതൽ സൂക്ഷ്മമായ ഒരു സംവിധാനം അവതരിപ്പിച്ചു.
മൈക്രോടാസ്ക്കുകൾ അവതരിപ്പിക്കുന്നു: ഉയർന്ന മുൻഗണന
പരമ്പരാഗത കോൾബാക്ക് ക്യൂവിനെ പലപ്പോഴും മാക്രോടാസ്ക് ക്യൂ അല്ലെങ്കിൽ ലളിതമായി ടാസ്ക് ക്യൂ എന്ന് വിളിക്കുന്നു. ഇതിന് വിപരീതമായി, മൈക്രോടാസ്ക്കുകൾ മാക്രോടാസ്ക്കുകളേക്കാൾ ഉയർന്ന മുൻഗണനയുള്ള ഒരു പ്രത്യേക ക്യൂവിനെ പ്രതിനിധീകരിക്കുന്നു. അസിൻക്രണസ് പ്രവർത്തനങ്ങളുടെ കൃത്യമായ എക്സിക്യൂഷൻ ക്രമം മനസ്സിലാക്കുന്നതിന് ഈ വേർതിരിവ് അത്യന്താപേക്ഷിതമാണ്.
എന്താണ് ഒരു മൈക്രോടാസ്ക് ആകുന്നത്?
- പ്രോമിസുകൾ (Promises): പ്രോമിസുകളുടെ ഫുൾഫിൽമെൻ്റ് അല്ലെങ്കിൽ റിജക്ഷൻ കോൾബാക്കുകൾ മൈക്രോടാസ്ക്കുകളായി ഷെഡ്യൂൾ ചെയ്യപ്പെടുന്നു. ഇതിൽ
.then(),.catch(),.finally()എന്നിവയ്ക്ക് നൽകുന്ന കോൾബാക്കുകൾ ഉൾപ്പെടുന്നു. queueMicrotask(): മൈക്രോടാസ്ക് ക്യൂവിലേക്ക് ടാസ്ക്കുകൾ ചേർക്കുന്നതിനായി പ്രത്യേകം രൂപകൽപ്പന ചെയ്ത ഒരു നേറ്റീവ് ജാവാസ്ക്രിപ്റ്റ് ഫംഗ്ഷൻ.- മ്യൂട്ടേഷൻ ഒബ്സെർവറുകൾ (Mutation Observers): DOM-ലെ മാറ്റങ്ങൾ നിരീക്ഷിക്കാനും അസിൻക്രണസായി കോൾബാക്കുകൾ ട്രിഗർ ചെയ്യാനും ഇവ ഉപയോഗിക്കുന്നു.
process.nextTick()(നോഡ്.ജെഎസ്-ന് മാത്രം): ആശയത്തിൽ സമാനമാണെങ്കിലും, നോഡ്.ജെഎസ്-ലെprocess.nextTick()-ന് ഇതിലും ഉയർന്ന മുൻഗണനയുണ്ട്, ഇത് ഏതെങ്കിലും I/O കോൾബാക്കുകൾക്കോ ടൈമറുകൾക്കോ മുൻപായി പ്രവർത്തിക്കുന്നു, ഫലത്തിൽ ഉയർന്ന തലത്തിലുള്ള ഒരു മൈക്രോടാസ്ക്കായി പ്രവർത്തിക്കുന്നു.
ഇവന്റ് ലൂപ്പിന്റെ മെച്ചപ്പെടുത്തിയ സൈക്കിൾ
മൈക്രോടാസ്ക് ക്യൂവിന്റെ ആവിർഭാവത്തോടെ ഇവന്റ് ലൂപ്പിന്റെ പ്രവർത്തനം കൂടുതൽ സങ്കീർണ്ണമാകുന്നു. മെച്ചപ്പെടുത്തിയ സൈക്കിൾ എങ്ങനെ പ്രവർത്തിക്കുന്നുവെന്ന് താഴെ നൽകുന്നു:
- നിലവിലെ കോൾ സ്റ്റാക്ക് എക്സിക്യൂട്ട് ചെയ്യുക: ഇവന്റ് ലൂപ്പ് ആദ്യം കോൾ സ്റ്റാക്ക് ശൂന്യമാണെന്ന് ഉറപ്പാക്കുന്നു.
- മൈക്രോടാസ്ക്കുകൾ പ്രോസസ്സ് ചെയ്യുക: കോൾ സ്റ്റാക്ക് ശൂന്യമായാൽ, ഇവന്റ് ലൂപ്പ് മൈക്രോടാസ്ക് ക്യൂ പരിശോധിക്കുന്നു. മൈക്രോടാസ്ക് ക്യൂ ശൂന്യമാകുന്നതുവരെ ക്യൂവിലുള്ള എല്ലാ മൈക്രോടാസ്ക്കുകളും ഒന്നൊന്നായി എക്സിക്യൂട്ട് ചെയ്യുന്നു. ഇതാണ് നിർണ്ണായക വ്യത്യാസം: ഓരോ മാക്രോടാസ്ക്കിനും അല്ലെങ്കിൽ സ്ക്രിപ്റ്റ് എക്സിക്യൂഷനും ശേഷം മൈക്രോടാസ്ക്കുകൾ ബാച്ചുകളായി പ്രോസസ്സ് ചെയ്യപ്പെടുന്നു.
- റെൻഡർ അപ്ഡേറ്റുകൾ (ബ്രൗസർ): ജാവാസ്ക്രിപ്റ്റ് എൻവയോൺമെന്റ് ഒരു ബ്രൗസറാണെങ്കിൽ, മൈക്രോടാസ്ക്കുകൾ പ്രോസസ്സ് ചെയ്ത ശേഷം അത് റെൻഡറിംഗ് അപ്ഡേറ്റുകൾ നടത്തിയേക്കാം.
- മാക്രോടാസ്ക്കുകൾ പ്രോസസ്സ് ചെയ്യുക: എല്ലാ മൈക്രോടാസ്ക്കുകളും ക്ലിയർ ചെയ്ത ശേഷം, ഇവന്റ് ലൂപ്പ് അടുത്ത മാക്രോടാസ്ക് (ഉദാഹരണത്തിന്, കോൾബാക്ക് ക്യൂവിൽ നിന്ന്,
setTimeoutപോലുള്ള ടൈമർ ക്യൂകളിൽ നിന്ന്, I/O ക്യൂകളിൽ നിന്ന്) തിരഞ്ഞെടുത്ത് കോൾ സ്റ്റാക്കിലേക്ക് പുഷ് ചെയ്യുന്നു. - ആവർത്തിക്കുക: സൈക്കിൾ പിന്നീട് ഘട്ടം 1-ൽ നിന്ന് ആവർത്തിക്കുന്നു.
ഇതിനർത്ഥം, ഒരൊറ്റ മാക്രോടാസ്ക് എക്സിക്യൂഷൻ അടുത്ത മാക്രോടാസ്ക് പരിഗണിക്കുന്നതിന് മുൻപ് നിരവധി മൈക്രോടാസ്ക്കുകളുടെ എക്സിക്യൂഷനിലേക്ക് നയിച്ചേക്കാം. ഇത് പ്രതികരണശേഷിയിലും എക്സിക്യൂഷൻ ക്രമത്തിലും കാര്യമായ പ്രത്യാഘാതങ്ങൾ ഉണ്ടാക്കും.
ടാസ്ക് ക്യൂ മുൻഗണന മനസ്സിലാക്കൽ: ഒരു പ്രായോഗിക കാഴ്ചപ്പാട്
ലോകമെമ്പാടുമുള്ള ഡെവലപ്പർമാർക്ക് പ്രസക്തമായ പ്രായോഗിക ഉദാഹരണങ്ങൾ ഉപയോഗിച്ച് നമുക്ക് ഇത് വ്യക്തമാക്കാം, വിവിധ സാഹചര്യങ്ങൾ പരിഗണിച്ച്:
ഉദാഹരണം 1: `setTimeout` vs. `Promise`
താഴെ പറയുന്ന കോഡ് സ്നിപ്പെറ്റ് പരിഗണിക്കുക:
console.log('Start');
setTimeout(function callback1() {
console.log('Timeout Callback 1');
}, 0);
Promise.resolve().then(function promiseCallback1() {
console.log('Promise Callback 1');
});
console.log('End');
ഔട്ട്പുട്ട് എന്തായിരിക്കുമെന്ന് നിങ്ങൾ കരുതുന്നു? ലണ്ടൻ, ന്യൂയോർക്ക്, ടോക്കിയോ, അല്ലെങ്കിൽ സിഡ്നി എന്നിവിടങ്ങളിലെ ഡെവലപ്പർമാർക്ക്, പ്രതീക്ഷ സ്ഥിരതയുള്ളതായിരിക്കണം:
console.log('Start');കോൾ സ്റ്റാക്കിൽ ഉള്ളതിനാൽ ഉടനടി എക്സിക്യൂട്ട് ചെയ്യുന്നു.setTimeoutനേരിടുന്നു. ടൈമർ 0ms ആയി സജ്ജീകരിച്ചിരിക്കുന്നു, പക്ഷേ പ്രധാനമായി, അതിന്റെ കോൾബാക്ക് ഫംഗ്ഷൻ ടൈമർ കാലഹരണപ്പെട്ടതിന് ശേഷം (അതായത് ഉടനടി) മാക്രോടാസ്ക് ക്യൂവിൽ സ്ഥാപിക്കപ്പെടുന്നു.Promise.resolve().then(...)നേരിടുന്നു. പ്രോമിസ് ഉടനടി റിസോൾവ് ആകുന്നു, അതിന്റെ കോൾബാക്ക് ഫംഗ്ഷൻ മൈക്രോടാസ്ക് ക്യൂവിൽ സ്ഥാപിക്കപ്പെടുന്നു.console.log('End');ഉടനടി എക്സിക്യൂട്ട് ചെയ്യുന്നു.
ഇപ്പോൾ, കോൾ സ്റ്റാക്ക് ശൂന്യമാണ്. ഇവന്റ് ലൂപ്പിന്റെ സൈക്കിൾ ആരംഭിക്കുന്നു:
- അത് മൈക്രോടാസ്ക് ക്യൂ പരിശോധിക്കുന്നു. അത്
promiseCallback1കണ്ടെത്തുകയും എക്സിക്യൂട്ട് ചെയ്യുകയും ചെയ്യുന്നു. - മൈക്രോടാസ്ക് ക്യൂ ഇപ്പോൾ ശൂന്യമാണ്.
- അത് മാക്രോടാസ്ക് ക്യൂ പരിശോധിക്കുന്നു. അത്
callback1(setTimeout-ൽ നിന്ന്) കണ്ടെത്തുകയും കോൾ സ്റ്റാക്കിലേക്ക് പുഷ് ചെയ്യുകയും ചെയ്യുന്നു. callback1എക്സിക്യൂട്ട് ചെയ്യുന്നു, 'Timeout Callback 1' എന്ന് ലോഗ് ചെയ്യുന്നു.
അതുകൊണ്ട്, ഔട്ട്പുട്ട് ഇതായിരിക്കും:
Start
End
Promise Callback 1
Timeout Callback 1
ഇത് വ്യക്തമായി കാണിക്കുന്നത്, `setTimeout`-ന് 0 ഡിലെ ആണെങ്കിലും, മൈക്രോടാസ്ക്കുകൾ (പ്രോമിസുകൾ) മാക്രോടാസ്ക്കുകൾക്ക് (setTimeout) മുൻപ് പ്രോസസ്സ് ചെയ്യപ്പെടുന്നു എന്നാണ്.
ഉദാഹരണം 2: നെസ്റ്റഡ് അസിൻക്രണസ് ഓപ്പറേഷനുകൾ
നെസ്റ്റഡ് ഓപ്പറേഷനുകൾ ഉൾപ്പെടുന്ന കൂടുതൽ സങ്കീർണ്ണമായ ഒരു സാഹചര്യം നമുക്ക് പരിശോധിക്കാം:
console.log('Script Start');
setTimeout(() => {
console.log('setTimeout 1');
Promise.resolve().then(() => console.log('Promise 1.1'));
setTimeout(() => console.log('setTimeout 1.1'), 0);
}, 0);
Promise.resolve().then(() => {
console.log('Promise 1');
setTimeout(() => console.log('setTimeout 2'), 0);
Promise.resolve().then(() => console.log('Promise 1.2'));
});
console.log('Script End');
എക്സിക്യൂഷൻ എങ്ങനെയാണെന്ന് നമുക്ക് നോക്കാം:
console.log('Script Start');'Script Start' എന്ന് ലോഗ് ചെയ്യുന്നു.- ആദ്യത്തെ
setTimeoutനേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`timeout1Callback` എന്ന് വിളിക്കാം) ഒരു മാക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. - ആദ്യത്തെ
Promise.resolve().then(...)നേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`promise1Callback`) ഒരു മൈക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. console.log('Script End');'Script End' എന്ന് ലോഗ് ചെയ്യുന്നു.
കോൾ സ്റ്റാക്ക് ഇപ്പോൾ ശൂന്യമാണ്. ഇവന്റ് ലൂപ്പ് ആരംഭിക്കുന്നു:
മൈക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 1):
- ഇവന്റ് ലൂപ്പ് മൈക്രോടാസ്ക് ക്യൂവിൽ `promise1Callback` കണ്ടെത്തുന്നു.
- `promise1Callback` എക്സിക്യൂട്ട് ചെയ്യുന്നു:
- 'Promise 1' ലോഗ് ചെയ്യുന്നു.
- ഒരു
setTimeoutനേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`timeout2Callback`) ഒരു മാക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. - മറ്റൊരു
Promise.resolve().then(...)നേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`promise1.2Callback`) ഒരു മൈക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. - മൈക്രോടാസ്ക് ക്യൂവിൽ ഇപ്പോൾ `promise1.2Callback` അടങ്ങിയിരിക്കുന്നു.
- ഇവന്റ് ലൂപ്പ് മൈക്രോടാസ്ക്കുകൾ പ്രോസസ്സ് ചെയ്യുന്നത് തുടരുന്നു. അത് `promise1.2Callback` കണ്ടെത്തി എക്സിക്യൂട്ട് ചെയ്യുന്നു.
- മൈക്രോടാസ്ക് ക്യൂ ഇപ്പോൾ ശൂന്യമാണ്.
മാക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 1):
- ഇവന്റ് ലൂപ്പ് മാക്രോടാസ്ക് ക്യൂ പരിശോധിക്കുന്നു. അത് `timeout1Callback` കണ്ടെത്തുന്നു.
- `timeout1Callback` എക്സിക്യൂട്ട് ചെയ്യുന്നു:
- 'setTimeout 1' ലോഗ് ചെയ്യുന്നു.
- ഒരു
Promise.resolve().then(...)നേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`promise1.1Callback`) ഒരു മൈക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. - മറ്റൊരു
setTimeoutനേരിടുന്നു. അതിന്റെ കോൾബാക്ക് (`timeout1.1Callback`) ഒരു മാക്രോടാസ്ക്കായി ക്യൂ ചെയ്യപ്പെടുന്നു. - മൈക്രോടാസ്ക് ക്യൂവിൽ ഇപ്പോൾ `promise1.1Callback` അടങ്ങിയിരിക്കുന്നു.
കോൾ സ്റ്റാക്ക് വീണ്ടും ശൂന്യമാണ്. ഇവന്റ് ലൂപ്പ് അതിന്റെ സൈക്കിൾ പുനരാരംഭിക്കുന്നു.
മൈക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 2):
- ഇവന്റ് ലൂപ്പ് മൈക്രോടാസ്ക് ക്യൂവിൽ `promise1.1Callback` കണ്ടെത്തി എക്സിക്യൂട്ട് ചെയ്യുന്നു.
- മൈക്രോടാസ്ക് ക്യൂ ഇപ്പോൾ ശൂന്യമാണ്.
മാക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 2):
- ഇവന്റ് ലൂപ്പ് മാക്രോടാസ്ക് ക്യൂ പരിശോധിക്കുന്നു. അത് `timeout2Callback` (ആദ്യത്തെ setTimeout-ന്റെ നെസ്റ്റഡ് setTimeout-ൽ നിന്ന്) കണ്ടെത്തുന്നു.
- `timeout2Callback` എക്സിക്യൂട്ട് ചെയ്യുന്നു, 'setTimeout 2' എന്ന് ലോഗ് ചെയ്യുന്നു.
- മാക്രോടാസ്ക് ക്യൂവിൽ ഇപ്പോൾ `timeout1.1Callback` അടങ്ങിയിരിക്കുന്നു.
കോൾ സ്റ്റാക്ക് വീണ്ടും ശൂന്യമാണ്. ഇവന്റ് ലൂപ്പ് അതിന്റെ സൈക്കിൾ പുനരാരംഭിക്കുന്നു.
മൈക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 3):
- മൈക്രോടാസ്ക് ക്യൂ ശൂന്യമാണ്.
മാക്രോടാസ്ക് ക്യൂ പ്രോസസ്സിംഗ് (റൗണ്ട് 3):
- ഇവന്റ് ലൂപ്പ് `timeout1.1Callback` കണ്ടെത്തി എക്സിക്യൂട്ട് ചെയ്യുന്നു, 'setTimeout 1.1' എന്ന് ലോഗ് ചെയ്യുന്നു.
ക്യൂകൾ ഇപ്പോൾ ശൂന്യമാണ്. അന്തിമ ഔട്ട്പുട്ട് ഇതായിരിക്കും:
Script Start
Script End
Promise 1
Promise 1.2
setTimeout 1
setTimeout 2
Promise 1.1
setTimeout 1.1
ഒരൊറ്റ മാക്രോടാസ്ക്കിന് മൈക്രോടാസ്ക്കുകളുടെ ഒരു ശൃംഖല എങ്ങനെ ട്രിഗർ ചെയ്യാമെന്നും, ഇവന്റ് ലൂപ്പ് അടുത്ത മാക്രോടാസ്ക് പരിഗണിക്കുന്നതിന് മുൻപ് അവയെല്ലാം എങ്ങനെ പ്രോസസ്സ് ചെയ്യപ്പെടുന്നുവെന്നും ഈ ഉദാഹരണം വ്യക്തമാക്കുന്നു.
ഉദാഹരണം 3: `requestAnimationFrame` vs. `setTimeout`
ബ്രൗസർ എൻവയോൺമെന്റുകളിൽ, requestAnimationFrame മറ്റൊരു കൗതുകകരമായ ഷെഡ്യൂളിംഗ് സംവിധാനമാണ്. ഇത് ആനിമേഷനുകൾക്കായി രൂപകൽപ്പന ചെയ്തിട്ടുള്ളതാണ്, സാധാരണയായി മാക്രോടാസ്ക്കുകൾക്ക് ശേഷവും മറ്റ് റെൻഡറിംഗ് അപ്ഡേറ്റുകൾക്ക് മുൻപും പ്രോസസ്സ് ചെയ്യപ്പെടുന്നു. ഇതിന്റെ മുൻഗണന സാധാരണയായി setTimeout(..., 0)-നേക്കാൾ കൂടുതലും മൈക്രോടാസ്ക്കുകളേക്കാൾ കുറവുമാണ്.
ഇത് പരിഗണിക്കുക:
console.log('Start');
setTimeout(() => console.log('setTimeout'), 0);
requestAnimationFrame(() => console.log('requestAnimationFrame'));
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
പ്രതീക്ഷിക്കുന്ന ഔട്ട്പുട്ട്:
Start
End
Promise
setTimeout
requestAnimationFrame
അതിന്റെ കാരണം ഇതാണ്:
- സ്ക്രിപ്റ്റ് എക്സിക്യൂഷൻ 'Start', 'End' എന്ന് ലോഗ് ചെയ്യുന്നു,
setTimeout-നായി ഒരു മാക്രോടാസ്ക് ക്യൂ ചെയ്യുന്നു, പ്രോമിസിനായി ഒരു മൈക്രോടാസ്ക് ക്യൂ ചെയ്യുന്നു. - ഇവന്റ് ലൂപ്പ് മൈക്രോടാസ്ക് പ്രോസസ്സ് ചെയ്യുന്നു: 'Promise' ലോഗ് ചെയ്യപ്പെടുന്നു.
- ഇവന്റ് ലൂപ്പ് പിന്നീട് മാക്രോടാസ്ക് പ്രോസസ്സ് ചെയ്യുന്നു: 'setTimeout' ലോഗ് ചെയ്യപ്പെടുന്നു.
- മാക്രോടാസ്ക്കുകളും മൈക്രോടാസ്ക്കുകളും കൈകാര്യം ചെയ്ത ശേഷം, ബ്രൗസറിന്റെ റെൻഡറിംഗ് പൈപ്പ്ലൈൻ ആരംഭിക്കുന്നു. അടുത്ത ഫ്രെയിം പെയിന്റ് ചെയ്യുന്നതിന് മുൻപ്, ഈ ഘട്ടത്തിലാണ്
requestAnimationFrameകോൾബാക്കുകൾ സാധാരണയായി എക്സിക്യൂട്ട് ചെയ്യപ്പെടുന്നത്. അതിനാൽ, 'requestAnimationFrame' ലോഗ് ചെയ്യപ്പെടുന്നു.
ഇന്ററാക്ടീവ് യുഐകൾ നിർമ്മിക്കുന്ന ഏതൊരു ആഗോള ഡെവലപ്പർക്കും ഇത് നിർണായകമാണ്, ഇത് ആനിമേഷനുകൾ സുഗമവും പ്രതികരണശേഷിയുള്ളതുമായി നിലനിർത്തുന്നു.
ആഗോള ഡെവലപ്പർമാർക്കുള്ള പ്രവർത്തനക്ഷമമായ ഉൾക്കാഴ്ചകൾ
ഇവന്റ് ലൂപ്പിന്റെ പ്രവർത്തനരീതികൾ മനസ്സിലാക്കുന്നത് ഒരു അക്കാദമിക് വ്യായാമമല്ല; ലോകമെമ്പാടുമുള്ള കരുത്തുറ്റ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിന് ഇതിന് വ്യക്തമായ നേട്ടങ്ങളുണ്ട്:
- പ്രവചിക്കാവുന്ന പ്രകടനം: എക്സിക്യൂഷൻ ക്രമം അറിയുന്നതിലൂടെ, നിങ്ങളുടെ കോഡ് എങ്ങനെ പെരുമാറുമെന്ന് നിങ്ങൾക്ക് മുൻകൂട്ടി കാണാൻ കഴിയും, പ്രത്യേകിച്ചും ഉപയോക്തൃ ഇടപെടലുകൾ, നെറ്റ്വർക്ക് അഭ്യർത്ഥനകൾ, അല്ലെങ്കിൽ ടൈമറുകൾ എന്നിവയുമായി ഇടപെഴകുമ്പോൾ. ഇത് ഒരു ഉപയോക്താവിന്റെ ഭൂമിശാസ്ത്രപരമായ സ്ഥാനം അല്ലെങ്കിൽ ഇന്റർനെറ്റ് വേഗത പരിഗണിക്കാതെ, കൂടുതൽ പ്രവചിക്കാവുന്ന ആപ്ലിക്കേഷൻ പ്രകടനത്തിലേക്ക് നയിക്കുന്നു.
- അപ്രതീക്ഷിത പെരുമാറ്റം ഒഴിവാക്കൽ: മൈക്രോടാസ്ക് vs മാക്രോടാസ്ക് മുൻഗണന തെറ്റിദ്ധരിക്കുന്നത് അപ്രതീക്ഷിത കാലതാമസങ്ങൾക്കോ ക്രമം തെറ്റിയുള്ള എക്സിക്യൂഷനോ ഇടയാക്കും, ഇത് വിതരണം ചെയ്ത സിസ്റ്റങ്ങൾ അല്ലെങ്കിൽ സങ്കീർണ്ണമായ അസിൻക്രണസ് വർക്ക്ഫ്ലോകളുള്ള ആപ്ലിക്കേഷനുകൾ ഡീബഗ് ചെയ്യുമ്പോൾ പ്രത്യേകിച്ചും നിരാശാജനകമാണ്.
- ഉപയോക്തൃ അനുഭവം ഒപ്റ്റിമൈസ് ചെയ്യൽ: ആഗോള പ്രേക്ഷകർക്ക് സേവനം നൽകുന്ന ആപ്ലിക്കേഷനുകൾക്ക്, പ്രതികരണശേഷി പ്രധാനമാണ്. സമയബന്ധിതമായ അപ്ഡേറ്റുകൾക്കായി പ്രോമിസുകളും
async/await-ഉം (മൈക്രോടാസ്ക്കുകളെ ആശ്രയിക്കുന്നവ) തന്ത്രപരമായി ഉപയോഗിക്കുന്നതിലൂടെ, പശ്ചാത്തല പ്രവർത്തനങ്ങൾ നടക്കുമ്പോഴും യുഐ സുഗമവും ഇന്ററാക്ടീവുമായി നിലനിൽക്കുന്നുവെന്ന് ഉറപ്പാക്കാൻ നിങ്ങൾക്ക് കഴിയും. ഉദാഹരണത്തിന്, ഒരു ഉപയോക്തൃ പ്രവർത്തനത്തിന് ശേഷം, കുറഞ്ഞ പ്രാധാന്യമുള്ള പശ്ചാത്തല ടാസ്ക്കുകൾ പ്രോസസ്സ് ചെയ്യുന്നതിന് മുൻപ് യുഐയുടെ ഒരു നിർണായക ഭാഗം ഉടനടി അപ്ഡേറ്റ് ചെയ്യുന്നത് പോലെ. - കാര്യക്ഷമമായ റിസോഴ്സ് മാനേജ്മെന്റ് (നോഡ്.ജെഎസ്): നോഡ്.ജെഎസ് എൻവയോൺമെന്റുകളിൽ,
process.nextTick()-ഉം മറ്റ് മൈക്രോടാസ്ക്കുകളുമായും മാക്രോടാസ്ക്കുകളുമായും ഉള്ള അതിന്റെ ബന്ധം മനസ്സിലാക്കുന്നത് അസിൻക്രണസ് I/O പ്രവർത്തനങ്ങൾ കാര്യക്ഷമമായി കൈകാര്യം ചെയ്യുന്നതിനും നിർണായക കോൾബാക്കുകൾ ഉടനടി പ്രോസസ്സ് ചെയ്യപ്പെടുന്നുവെന്ന് ഉറപ്പാക്കുന്നതിനും അത്യന്താപേക്ഷിതമാണ്. - സങ്കീർണ്ണമായ അസിൻക്രണസിറ്റി ഡീബഗ് ചെയ്യൽ: ഡീബഗ് ചെയ്യുമ്പോൾ, ബ്രൗസർ ഡെവലപ്പർ ടൂളുകൾ (ക്രോം ഡെവ്ടൂൾസിന്റെ പെർഫോമൻസ് ടാബ് പോലുള്ളവ) അല്ലെങ്കിൽ നോഡ്.ജെഎസ് ഡീബഗ്ഗിംഗ് ടൂളുകൾ ഉപയോഗിക്കുന്നത് ഇവന്റ് ലൂപ്പിന്റെ പ്രവർത്തനം ദൃശ്യപരമായി പ്രതിനിധീകരിക്കാനും, തടസ്സങ്ങൾ തിരിച്ചറിയാനും എക്സിക്യൂഷന്റെ ഒഴുക്ക് മനസ്സിലാക്കാനും നിങ്ങളെ സഹായിക്കും.
അസിൻക്രണസ് കോഡിനുള്ള മികച്ച രീതികൾ
- ഉടനടി തുടർച്ചകൾക്കായി പ്രോമിസുകളും
async/await-ഉം തിരഞ്ഞെടുക്കുക: ഒരു അസിൻക്രണസ് ഓപ്പറേഷന്റെ ഫലം മറ്റൊരു ഉടനടി പ്രവർത്തനത്തെയോ അപ്ഡേറ്റിനെയോ ട്രിഗർ ചെയ്യണമെങ്കിൽ, പ്രോമിസുകളോasync/await-ഓ ആണ് സാധാരണയായി തിരഞ്ഞെടുക്കപ്പെടുന്നത്, കാരണം അവയുടെ മൈക്രോടാസ്ക് ഷെഡ്യൂളിംഗ്setTimeout(..., 0)-മായി താരതമ്യപ്പെടുത്തുമ്പോൾ വേഗതയേറിയ എക്സിക്യൂഷൻ ഉറപ്പാക്കുന്നു. - ഇവന്റ് ലൂപ്പിന് വഴങ്ങാൻ
setTimeout(..., 0)ഉപയോഗിക്കുക: ചിലപ്പോൾ, ഒരു ടാസ്ക് അടുത്ത മാക്രോടാസ്ക് സൈക്കിളിലേക്ക് മാറ്റിവയ്ക്കാൻ നിങ്ങൾ ആഗ്രഹിച്ചേക്കാം. ഉദാഹരണത്തിന്, ബ്രൗസറിന് റെൻഡർ അപ്ഡേറ്റുകൾ അനുവദിക്കുന്നതിനോ അല്ലെങ്കിൽ ദൈർഘ്യമേറിയ സിൻക്രണസ് പ്രവർത്തനങ്ങളെ വിഭജിക്കുന്നതിനോ. - നെസ്റ്റഡ് അസിൻക്രണസിറ്റിയെക്കുറിച്ച് ശ്രദ്ധാലുവായിരിക്കുക: ഉദാഹരണങ്ങളിൽ കണ്ടതുപോലെ, ആഴത്തിൽ നെസ്റ്റ് ചെയ്ത അസിൻക്രണസ് കോളുകൾ കോഡ് മനസ്സിലാക്കാൻ പ്രയാസകരമാക്കും. സാധ്യമാകുന്നിടത്ത് നിങ്ങളുടെ അസിൻക്രണസ് ലോജിക് ഫ്ലാറ്റൻ ചെയ്യുന്നതിനോ സങ്കീർണ്ണമായ അസിൻക്രണസ് ഫ്ലോകൾ കൈകാര്യം ചെയ്യാൻ സഹായിക്കുന്ന ലൈബ്രറികൾ ഉപയോഗിക്കുന്നതിനോ പരിഗണിക്കുക.
- എൻവയോൺമെന്റ് വ്യത്യാസങ്ങൾ മനസ്സിലാക്കുക: പ്രധാന ഇവന്റ് ലൂപ്പ് തത്വങ്ങൾ സമാനമാണെങ്കിലും, പ്രത്യേക പെരുമാറ്റങ്ങൾ (നോഡ്.ജെഎസ്-ലെ
process.nextTick()പോലുള്ളവ) വ്യത്യാസപ്പെടാം. നിങ്ങളുടെ കോഡ് പ്രവർത്തിക്കുന്ന എൻവയോൺമെന്റിനെക്കുറിച്ച് എപ്പോഴും ബോധവാന്മാരായിരിക്കുക. - വ്യത്യസ്ത സാഹചര്യങ്ങളിൽ പരീക്ഷിക്കുക: ഒരു ആഗോള പ്രേക്ഷകർക്കായി, ഒരു സ്ഥിരമായ അനുഭവം ഉറപ്പാക്കുന്നതിന് വിവിധ നെറ്റ്വർക്ക് സാഹചര്യങ്ങളിലും ഉപകരണ ശേഷികളിലും നിങ്ങളുടെ ആപ്ലിക്കേഷന്റെ പ്രതികരണശേഷി പരീക്ഷിക്കുക.
ഉപസംഹാരം
ജാവാസ്ക്രിപ്റ്റ് ഇവന്റ് ലൂപ്പ്, മൈക്രോടാസ്ക്കുകൾക്കും മാക്രോടാസ്ക്കുകൾക്കുമായുള്ള അതിന്റെ വ്യത്യസ്ത ക്യൂകളോടൊപ്പം, ജാവാസ്ക്രിപ്റ്റിന്റെ അസിൻക്രണസ് സ്വഭാവത്തിന് ശക്തി പകരുന്ന നിശബ്ദ എഞ്ചിനാണ്. ലോകമെമ്പാടുമുള്ള ഡെവലപ്പർമാർക്ക്, അതിന്റെ മുൻഗണനാ സംവിധാനത്തെക്കുറിച്ചുള്ള സമഗ്രമായ ധാരണ കേവലം ഒരു അക്കാദമിക് കൗതുകമല്ല, മറിച്ച് ഉയർന്ന നിലവാരമുള്ളതും പ്രതികരണശേഷിയുള്ളതും മികച്ച പ്രകടനമുള്ളതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിനുള്ള ഒരു പ്രായോഗിക ആവശ്യകതയാണ്. കോൾ സ്റ്റാക്ക്, മൈക്രോടാസ്ക് ക്യൂ, മാക്രോടാസ്ക് ക്യൂ എന്നിവ തമ്മിലുള്ള പരസ്പരബന്ധം മാസ്റ്റർ ചെയ്യുന്നതിലൂടെ, നിങ്ങൾക്ക് കൂടുതൽ പ്രവചിക്കാവുന്ന കോഡ് എഴുതാനും ഉപയോക്തൃ അനുഭവം ഒപ്റ്റിമൈസ് ചെയ്യാനും ഏത് ഡെവലപ്മെന്റ് എൻവയോൺമെന്റിലും സങ്കീർണ്ണമായ അസിൻക്രണസ് വെല്ലുവിളികളെ ആത്മവിശ്വാസത്തോടെ നേരിടാനും കഴിയും.
പരീക്ഷണം തുടരുക, പഠനം തുടരുക, സന്തോഷകരമായ കോഡിംഗ്!