திறமையான ஸ்ட்ரீம் உருவாக்கம், பெரிய தரவுத்தொகுப்புகளைக் கையாளுதல், மற்றும் உலகளவில் பதிலளிக்கக்கூடிய பயன்பாடுகளை உருவாக்க ஜாவாஸ்கிரிப்ட் அசிங்க் ஜெனரேட்டர்களின் ஆற்றலைத் திறந்திடுங்கள். நடைமுறை வடிவங்கள் மற்றும் மேம்பட்ட நுட்பங்களைக் கற்றுக்கொள்ளுங்கள்.
ஜாவாஸ்கிரிப்ட் அசிங்க் ஜெனரேட்டர்களில் தேர்ச்சி பெறுதல்: ஸ்ட்ரீம் உருவாக்க உதவிகளுக்கான உங்கள் முழுமையான வழிகாட்டி
ஒன்றோடொன்று இணைக்கப்பட்ட டிஜிட்டல் உலகில், பயன்பாடுகள் தொடர்ந்து தரவு ஓட்டங்களைக் கையாளுகின்றன. நிகழ்நேரப் புதுப்பிப்புகள் மற்றும் பெரிய கோப்புச் செயலாக்கம் முதல் தொடர்ச்சியான ஏபிஐ தொடர்புகள் வரை, தரவு ஸ்ட்ரீம்களைத் திறமையாக நிர்வகித்து ಪ್ರತிக்ரியையாற்றும் திறன் முதன்மையானது. பாரம்பரிய ஒத்திசைவற்ற நிரலாக்க முறைகள், சக்திவாய்ந்தவையாக இருந்தாலும், உண்மையான மாறும், எல்லையற்ற தரவுத் தொடர்களைக் கையாளும்போது பெரும்பாலும் பின்தங்கிவிடுகின்றன. இங்குதான் ஜாவாஸ்கிரிப்ட்டின் அசிங்க் ஜெனரேட்டர்கள் ஒரு திருப்புமுனையாக வெளிப்படுகின்றன, இது தரவு ஸ்ட்ரீம்களை உருவாக்குவதற்கும் பயன்படுத்துவதற்கும் ஒரு நேர்த்தியான மற்றும் வலுவான வழிமுறையை வழங்குகிறது.
இந்த விரிவான வழிகாட்டி அசிங்க் ஜெனரேட்டர்களின் உலகிற்குள் ஆழமாகச் செல்கிறது, அவற்றின் அடிப்படைக் கருத்துக்கள், ஸ்ட்ரீம் உருவாக்கும் உதவியாளர்களாக அவற்றின் நடைமுறைப் பயன்பாடுகள், மற்றும் உலகெங்கிலும் உள்ள டெவலப்பர்களுக்கு அதிக செயல்திறன், மீள்திறன் மற்றும் பதிலளிக்கக்கூடிய பயன்பாடுகளை உருவாக்க அதிகாரம் அளிக்கும் மேம்பட்ட முறைகளை விளக்குகிறது. நீங்கள் பெரிய தரவுத்தொகுப்புகளைக் கையாளும் ஒரு அனுபவமுள்ள பின்தளப் பொறியாளராக இருந்தாலும், தடையற்ற பயனர் அனுபவங்களுக்கு முயற்சிக்கும் ஒரு முன்பக்க டெவலப்பராக இருந்தாலும், அல்லது சிக்கலான ஸ்ட்ரீம்களைச் செயலாக்கும் ஒரு தரவு விஞ்ஞானியாக இருந்தாலும், அசிங்க் ஜெனரேட்டர்களைப் புரிந்துகொள்வது உங்கள் கருவிப்பெட்டியை கணிசமாக மேம்படுத்தும்.
ஒத்திசைவற்ற ஜாவாஸ்கிரிப்ட் அடிப்படைகளைப் புரிந்துகொள்ளுதல்: ஸ்ட்ரீம்களுக்கான ஒரு பயணம்
அசிங்க் ஜெனரேட்டர்களின் நுணுக்கங்களுக்குள் நாம் மூழ்குவதற்கு முன், ஜாவாஸ்கிரிப்டில் ஒத்திசைவற்ற நிரலாக்கத்தின் பரிணாம வளர்ச்சியைப் பாராட்டுவது அவசியம். இந்தப் பயணம் அசிங்க் ஜெனரேட்டர்கள் போன்ற மிகவும் அதிநவீன கருவிகளின் வளர்ச்சிக்கு வழிவகுத்த சவால்களை எடுத்துக்காட்டுகிறது.
கால்பேக்குகள் மற்றும் கால்பேக் ஹெல் (Callback Hell)
ஆரம்பகால ஜாவாஸ்கிரிப்ட் ஒத்திசைவற்ற செயல்பாடுகளுக்கு கால்பேக்குகளை பெரிதும் நம்பியிருந்தது. ஒரு ஒத்திசைவற்ற பணி முடிந்தவுடன் செயல்படுத்தப்படும் மற்றொரு செயல்பாட்டை (கால்பேக்) செயல்பாடுகள் ஏற்கும். இது அடிப்படையாக இருந்தாலும், இந்த முறை பெரும்பாலும் ஆழமாகப் பதிக்கப்பட்ட குறியீடு கட்டமைப்புகளுக்கு வழிவகுத்தது, இது 'கால்பேக் ஹெல்' அல்லது 'டூம் பிரமிட்' என்று பிரபலமாக அறியப்பட்டது, இதனால் குறியீட்டைப் படிப்பது, பராமரிப்பது மற்றும் பிழைதிருத்தம் செய்வது கடினமாக இருந்தது, குறிப்பாக தொடர்ச்சியான ஒத்திசைவற்ற செயல்பாடுகள் அல்லது பிழைப் பரவலைக் கையாளும்போது.
function fetchData(url, callback) {
// Simulate async operation
setTimeout(() => {
const data = `Data from ${url}`;
callback(null, data);
}, 1000);
}
fetchData('api/users', (err, userData) => {
if (err) { console.error(err); return; }
fetchData('api/products', (err, productData) => {
if (err) { console.error(err); return; }
console.log(userData, productData);
});
});
ப்ராமிஸ்கள் (Promises): ஒரு படி முன்னேற்றம்
கால்பேக் ஹெல்லைத் தணிக்க ப்ராமிஸ்கள் அறிமுகப்படுத்தப்பட்டன, இது ஒத்திசைவற்ற செயல்பாடுகளைக் கையாள மிகவும் கட்டமைக்கப்பட்ட வழியை வழங்கியது. ஒரு ப்ராமிஸ் ஒரு ஒத்திசைவற்ற செயல்பாட்டின் இறுதி நிறைவையும் (அல்லது தோல்வியையும்) மற்றும் அதன் விளைவான மதிப்பையும் குறிக்கிறது. அவை மெத்தட் செயினிங்கை (`.then()`, `.catch()`, `.finally()`) அறிமுகப்படுத்தின, இது பதிக்கப்பட்ட குறியீட்டைத் தட்டையாக்கியது, பிழை கையாளுதலை மேம்படுத்தியது மற்றும் ஒத்திசைவற்ற தொடர்களை மேலும் படிக்கக்கூடியதாக மாற்றியது.
function fetchDataPromise(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// Simulate success or failure
if (Math.random() > 0.1) {
resolve(`Data from ${url}`);
} else {
reject(new Error(`Failed to fetch ${url}`));
}
}, 500);
});
}
fetchDataPromise('api/users')
.then(userData => fetchDataPromise('api/products'))
.then(productData => console.log('All data fetched:', productData))
.catch(error => console.error('Error fetching data:', error));
அசிங்க்/அவெயிட் (Async/Await): ப்ராமிஸ்களுக்கான தொடரியல் சர்க்கரை
ப்ராமிஸ்களின் அடிப்படையில், `async`/`await` ஒரு தொடரியல் சர்க்கரையாக வந்தது, இது ஒத்திசைவற்ற குறியீட்டை ஒத்திசைவான பாணியில் எழுத அனுமதித்தது. ஒரு `async` செயல்பாடு மறைமுகமாக ஒரு ப்ராமிஸைத் திருப்பியனுப்புகிறது, மற்றும் `await` முக்கியச்சொல் ஒரு ப்ராமிஸ் தீர்க்கப்படும் வரை (தீர்க்கப்பட்டாலோ அல்லது நிராகரிக்கப்பட்டாலோ) ஒரு `async` செயல்பாட்டின் செயலாக்கத்தை நிறுத்துகிறது. இது வாசிப்புத்திறனைப் பெரிதும் மேம்படுத்தியது மற்றும் நிலையான `try...catch` பிளாக்குகள் மூலம் பிழை கையாளுதலை எளிதாக்கியது.
async function fetchAllData() {
try {
const userData = await fetchDataPromise('api/users');
const productData = await fetchDataPromise('api/products');
console.log('All data fetched using async/await:', userData, productData);
} catch (error) {
console.error('Error in fetchAllData:', error);
}
}
fetchAllData();
`async`/`await` ஒற்றை ஒத்திசைவற்ற செயல்பாடுகளை அல்லது ஒரு நிலையான வரிசையை மிக நன்றாகக் கையாளும் அதே வேளையில், அவை காலப்போக்கில் பல மதிப்புகளை 'இழுக்க' அல்லது மதிப்புகள் இடைக்கிடை உற்பத்தி செய்யப்படும் தொடர்ச்சியான ஸ்ட்ரீமைக் குறிக்க ஒரு வழிமுறையை இயல்பாக வழங்காது. இந்த இடைவெளியைத்தான் அசிங்க் ஜெனரேட்டர்கள் நேர்த்தியாக நிரப்புகின்றன.
ஜெனரேட்டர்களின் சக்தி: சுழற்சி மற்றும் கட்டுப்பாட்டு ஓட்டம்
அசிங்க் ஜெனரேட்டர்களை முழுமையாகப் புரிந்துகொள்ள, முதலில் அவற்றின் ஒத்திசைவான đối tác களைப் புரிந்துகொள்வது முக்கியம். ECMAScript 2015 (ES6) இல் அறிமுகப்படுத்தப்பட்ட ஜெனரேட்டர்கள், இட்டரேட்டர்களை உருவாக்கவும் கட்டுப்பாட்டு ஓட்டத்தை நிர்வகிக்கவும் ஒரு சக்திவாய்ந்த வழியை வழங்குகின்றன.
ஒத்திசைவான ஜெனரேட்டர்கள் (`function*`)
ஒரு ஒத்திசைவான ஜெனரேட்டர் செயல்பாடு `function*` ஐப் பயன்படுத்தி வரையறுக்கப்படுகிறது. இது அழைக்கப்படும்போது, அது உடனடியாக அதன் உடலைச் செயல்படுத்தாது, ஆனால் ஒரு இட்டரேட்டர் பொருளைத் திருப்பி அனுப்புகிறது. இந்த இட்டரேட்டரை ஒரு `for...of` லூப்பைப் பயன்படுத்தி அல்லது அதன் `next()` முறையை மீண்டும் மீண்டும் அழைப்பதன் மூலம் சுழற்சி செய்யலாம். முக்கிய அம்சம் `yield` முக்கியச்சொல் ஆகும், இது ஜெனரேட்டரின் செயலாக்கத்தை நிறுத்தி, அழைப்பாளருக்கு ஒரு மதிப்பைத் திருப்பி அனுப்புகிறது. `next()` மீண்டும் அழைக்கப்படும்போது, ஜெனரேட்டர் அது விட்ட இடத்திலிருந்து மீண்டும் தொடங்குகிறது.
ஒரு ஒத்திசைவான ஜெனரேட்டரின் கட்டமைப்பு
- `function*` முக்கியச்சொல்: ஒரு ஜெனரேட்டர் செயல்பாட்டை அறிவிக்கிறது.
- `yield` முக்கியச்சொல்: செயலாக்கத்தை நிறுத்தி ஒரு மதிப்பைத் திருப்பி அனுப்புகிறது. இது ஒரு `return` போன்றது, இது செயல்பாட்டைப் பின்னர் மீண்டும் தொடங்க அனுமதிக்கிறது.
- `next()` முறை: ஜெனரேட்டர் செயல்பாட்டால் திருப்பியனுப்பப்பட்ட இட்டரேட்டரில் அழைக்கப்பட்டு, அதன் செயலாக்கத்தை மீண்டும் தொடங்கவும், அடுத்த விளைந்த மதிப்பைப் பெறவும் (அல்லது முடிந்தவுடன் `done: true`).
function* countUpTo(limit) {
let i = 1;
while (i <= limit) {
yield i; // Pause and yield current value
i++; // Resume and increment for next iteration
}
}
// Consuming the generator
const counter = countUpTo(3);
console.log(counter.next()); // { value: 1, done: false }
console.log(counter.next()); // { value: 2, done: false }
console.log(counter.next()); // { value: 3, done: false }
console.log(counter.next()); // { value: undefined, done: true }
// Or using a for...of loop (preferred for simple consumption)
console.log('\nUsing for...of:');
for (const num of countUpTo(5)) {
console.log(num);
}
// Output:
// 1
// 2
// 3
// 4
// 5
ஒத்திசைவான ஜெனரேட்டர்களின் பயன்பாடுகள்
- தனிப்பயன் இட்டரேட்டர்கள்: சிக்கலான தரவுக் கட்டமைப்புகளுக்குத் தனிப்பயன் இட்டரேபிள் பொருட்களை எளிதாக உருவாக்குங்கள்.
- எல்லையற்ற தொடர்கள்: நினைவகத்தில் பொருந்தாத தொடர்களை உருவாக்குங்கள் (உதாரணமாக, ஃபிபோனச்சி எண்கள், பகா எண்கள்), ஏனெனில் மதிப்புகள் தேவைக்கேற்ப உருவாக்கப்படுகின்றன.
- நிலை மேலாண்மை: நிலை இயந்திரங்கள் அல்லது நீங்கள் தர்க்கத்தை நிறுத்த/மீண்டும் தொடங்க வேண்டிய சூழ்நிலைகளுக்குப் பயனுள்ளது.
அசிங்க் ஜெனரேட்டர்களை அறிமுகப்படுத்துதல் (`async function*`): ஸ்ட்ரீம் உருவாக்குபவர்கள்
இப்போது, ஜெனரேட்டர்களின் சக்தியை ஒத்திசைவற்ற நிரலாக்கத்துடன் இணைப்போம். ஒரு அசிங்க் ஜெனரேட்டர் (`async function*`) என்பது ஒரு செயல்பாடாகும், இது உள்ளுக்குள் ப்ராமிஸ்களை `await` செய்ய முடியும் மற்றும் ஒத்திசைவற்ற முறையில் மதிப்புகளை `yield` செய்ய முடியும். இது ஒரு அசிங்க் இட்டரேட்டரைத் திருப்பி அனுப்புகிறது, இதை `for await...of` லூப்பைப் பயன்படுத்திப் பயன்படுத்தலாம்.
ஒத்திசைவற்ற தன்மையையும் சுழற்சியையும் இணைத்தல்
`async function*` இன் முக்கியப் புதுமை அதன் `yield await` செய்யும் திறன் ஆகும். இதன் பொருள் ஒரு ஜெனரேட்டர் ஒரு ஒத்திசைவற்ற செயல்பாட்டைச் செய்ய முடியும், அதன் முடிவை `await` செய்ய முடியும், பின்னர் அந்த முடிவை `yield` செய்ய முடியும், அடுத்த `next()` அழைப்பு வரை இடைநிறுத்தப்படும். இந்த முறை காலப்போக்கில் வரும் மதிப்புகளின் தொடர்களைப் பிரதிநிதித்துவப்படுத்த மிகவும் சக்தி வாய்ந்தது, திறம்பட ஒரு 'இழுத்தல்-அடிப்படையிலான' ஸ்ட்ரீமை உருவாக்குகிறது.
உந்துதல்-அடிப்படையிலான ஸ்ட்ரீம்களைப் போலல்லாமல் (உதாரணமாக, நிகழ்வு உமிழ்ப்பான்கள்), அங்கு தயாரிப்பாளர் வேகத்தை ஆணையிடுகிறார், இழுத்தல்-அடிப்படையிலான ஸ்ட்ரீம்கள் நுகர்வோர் தயாராக இருக்கும்போது அடுத்த தரவுத் தொகுதியைக் கோர அனுமதிக்கின்றன. இது பின்தள்ளலைக் (backpressure) கையாளுவதற்கு முக்கியமானது - தயாரிப்பாளர் நுகர்வோரை அது செயலாக்கக்கூடியதை விட வேகமாகத் தரவுகளால் மூழ்கடிப்பதைத் தடுக்கிறது.
ஒரு அசிங்க் ஜெனரேட்டரின் கட்டமைப்பு
- `async function*` முக்கியச்சொல்: ஒரு அசிங்க் ஜெனரேட்டர் செயல்பாட்டை அறிவிக்கிறது.
- `yield` முக்கியச்சொல்: செயலாக்கத்தை நிறுத்தி, விளைந்த மதிப்புக்குத் தீர்க்கும் ஒரு ப்ராமிஸைத் திருப்பி அனுப்புகிறது.
- `await` முக்கியச்சொல்: ஒரு ப்ராமிஸ் தீர்க்கப்படும் வரை செயலாக்கத்தை நிறுத்த ஜெனரேட்டருக்குள் பயன்படுத்தலாம்.
- `for await...of` லூப்: ஒரு அசிங்க் இட்டரேட்டரைப் பயன்படுத்துவதற்கான முதன்மை வழி, அதன் விளைந்த மதிப்புகளை ஒத்திசைவற்ற முறையில் சுழற்சி செய்வது.
async function* generateMessages() {
yield 'Hello';
// Simulate an async operation like fetching from a network
await new Promise(resolve => setTimeout(resolve, 1000));
yield 'World';
await new Promise(resolve => setTimeout(resolve, 500));
yield 'from Async Generator!';
}
// Consuming the async generator
async function consumeMessages() {
console.log('Starting message consumption...');
for await (const msg of generateMessages()) {
console.log(msg);
}
console.log('Finished message consumption.');
}
consumeMessages();
// Output will appear with delays:
// Starting message consumption...
// Hello
// (1 second delay)
// World
// (0.5 second delay)
// from Async Generator!
// Finished message consumption.
ஸ்ட்ரீம்களுக்கு அசிங்க் ஜெனரேட்டர்களின் முக்கிய நன்மைகள்
அசிங்க் ஜெனரேட்டர்கள் கட்டாயமான நன்மைகளை வழங்குகின்றன, அவற்றை ஸ்ட்ரீம் உருவாக்கம் மற்றும் நுகர்வுக்கு ஏற்றதாக ஆக்குகின்றன:
- இழுத்தல்-அடிப்படையிலான நுகர்வு: நுகர்வோர் ஓட்டத்தைக் கட்டுப்படுத்துகிறார். அது தயாராக இருக்கும்போது தரவைக் கோருகிறது, இது பின்தள்ளலைக் கையாளுவதற்கும் வளப் பயன்பாட்டை மேம்படுத்துவதற்கும் அடிப்படையானது. இது குறிப்பாக உலகளாவிய பயன்பாடுகளில் மதிப்புமிக்கது, அங்கு நெட்வொர்க் தாமதம் அல்லது மாறுபடும் வாடிக்கையாளர் திறன்கள் தரவுச் செயலாக்க வேகத்தைப் பாதிக்கலாம்.
- நினைவகத் திறன்: தரவு முழுமையாக நினைவகத்தில் ஏற்றப்படுவதற்குப் பதிலாக, படிப்படியாக, துண்டு துண்டாகச் செயலாக்கப்படுகிறது. இது மிக பெரிய தரவுத்தொகுப்புகளுடன் (உதாரணமாக, ஜிகாபைட்கள் பதிவுகள், பெரிய தரவுத்தள டம்ப்கள், உயர்-தெளிவுத்திறன் ஊடக ஸ்ட்ரீம்கள்) கையாளும்போது முக்கியமானது, இல்லையெனில் கணினி நினைவகத்தை தீர்த்துவிடும்.
- பின்தள்ளல் கையாளுதல்: நுகர்வோர் தரவை 'இழுப்பதால்', நுகர்வோர் வேகத்தைக் குறைக்க முடியாவிட்டால் தயாரிப்பாளர் தானாகவே வேகத்தைக் குறைத்துக்கொள்கிறார். இது வளத் தீர்வையும் தடுக்கிறது மற்றும் நிலையான பயன்பாட்டுச் செயல்திறனை உறுதி செய்கிறது, குறிப்பாக சேவைச் சுமைகள் ஏற்ற இறக்கமாக இருக்கும் விநியோகிக்கப்பட்ட அமைப்புகள் அல்லது மைக்ரோ சர்வீசஸ் கட்டமைப்புகளில் இது முக்கியமானது.
- எளிதாக்கப்பட்ட வள மேலாண்மை: ஜெனரேட்டர்கள் `try...finally` பிளாக்குகளைச் சேர்க்கலாம், இது ஜெனரேட்டர் சாதாரணமாக முடிந்தாலோ அல்லது நுகர்வோரின் `for await...of` லூப்பில் `break` அல்லது `return` மூலம் முன்கூட்டியே நிறுத்தப்பட்டாலோ வளங்களை (உதாரணமாக, கோப்பு கையாளுதல்கள், தரவுத்தள இணைப்புகள், நெட்வொர்க் சாக்கெட்டுகள்) கண்ணியமாக சுத்தம் செய்ய அனுமதிக்கிறது.
- குழாய்வழி மற்றும் உருமாற்றம்: சக்திவாய்ந்த தரவு செயலாக்கக் குழாய்களை உருவாக்க அசிங்க் ஜெனரேட்டர்களை எளிதாக ஒன்றாகச் சங்கிலிப்படுத்தலாம். ஒரு ஜெனரேட்டரின் வெளியீடு மற்றொரு ஜெனரேட்டரின் உள்ளீடாக மாறலாம், இது சிக்கலான தரவு உருமாற்றங்கள் மற்றும் வடிகட்டுதல்களை அதிக வாசிப்புத்திறன் மற்றும் மட்டுப்படுத்தப்பட்ட பாணியில் செயல்படுத்துகிறது.
- வாசிப்புத்திறன் மற்றும் பராமரிப்புத்திறன்: ஜெனரேட்டர்களின் சுழற்சித் தன்மையுடன் இணைந்த `async`/`await` தொடரியல், ஒத்திசைவான தர்க்கத்தை நெருக்கமாக ஒத்திருக்கும் குறியீட்டில் விளைகிறது, இது சிக்கலான ஒத்திசைவற்ற தரவு ஓட்டங்களை பதிக்கப்பட்ட கால்பேக்குகள் அல்லது சிக்கலான ப்ராமிஸ் சங்கிலிகளுடன் ஒப்பிடும்போது புரிந்துகொள்வதற்கும் பிழைதிருத்தம் செய்வதற்கும் மிகவும் எளிதாக்குகிறது.
நடைமுறைப் பயன்பாடுகள்: ஸ்ட்ரீம் உருவாக்க உதவிகள்
நவீன பயன்பாட்டு மேம்பாட்டில் பொதுவான சவால்களுக்கு நேர்த்தியான தீர்வுகளை வழங்கும், ஸ்ட்ரீம் உருவாக்க உதவியாளர்களாக அசிங்க் ஜெனரேட்டர்கள் பிரகாசிக்கும் நடைமுறைச் சூழ்நிலைகளை ஆராய்வோம்.
பக்கப்படுத்தப்பட்ட ஏபிஐகளிலிருந்து தரவை ஸ்ட்ரீமிங் செய்தல்
பல REST ஏபிஐக்கள் பேலோட் அளவைக் கட்டுப்படுத்தவும் பதிலளிக்கும் தன்மையை மேம்படுத்தவும் தரவைப் பக்கப்படுத்தப்பட்ட துண்டுகளில் திருப்பி அனுப்புகின்றன. எல்லாத் தரவையும் பெறுவது பொதுவாக பல தொடர்ச்சியான கோரிக்கைகளைச் செய்வதை உள்ளடக்கியது. அசிங்க் ஜெனரேட்டர்கள் இந்த பக்கப்படுத்தல் தர்க்கத்தை अमूर्तமாக்கலாம், எத்தனை நெட்வொர்க் கோரிக்கைகள் சம்பந்தப்பட்டிருந்தாலும், நுகர்வோருக்கு எல்லாப் பொருட்களின் ஒன்றிணைந்த, சுழற்சி செய்யக்கூடிய ஸ்ட்ரீமை வழங்கலாம்.
சூழ்நிலை: ஒரு பக்கத்திற்கு 50 வாடிக்கையாளர்களைத் திருப்பி அனுப்பும் ஒரு உலகளாவிய CRM அமைப்பு ஏபிஐயிலிருந்து அனைத்து வாடிக்கையாளர் பதிவுகளையும் பெறுதல்.
async function* fetchAllCustomers(baseUrl, initialPage = 1) {
let currentPage = initialPage;
let hasMore = true;
while (hasMore) {
const url = `
${baseUrl}/customers?page=${currentPage}&limit=50
`;
console.log(`Fetching page ${currentPage} from ${url}`);
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
// Assuming 'customers' array and 'total_pages'/'next_page' in response
if (data && Array.isArray(data.customers) && data.customers.length > 0) {
yield* data.customers; // Yield each customer from the current page
if (data.next_page) { // Or check for total_pages and current_page
currentPage++;
} else {
hasMore = false;
}
} else {
hasMore = false; // No more customers or empty response
}
} catch (error) {
console.error(`Error fetching page ${currentPage}:`, error.message);
hasMore = false; // Stop on error, or implement retry logic
}
}
}
// --- Consumption Example ---
async function processCustomers() {
const customerApiUrl = 'https://api.example.com'; // Replace with your actual API base URL
let totalProcessed = 0;
try {
for await (const customer of fetchAllCustomers(customerApiUrl)) {
console.log(`Processing customer: ${customer.id} - ${customer.name}`);
// Simulate some async processing like saving to a database or sending an email
await new Promise(resolve => setTimeout(resolve, 50));
totalProcessed++;
// Example: Stop early if a certain condition is met or for testing
if (totalProcessed >= 150) {
console.log('Processed 150 customers. Stopping early.');
break; // This will gracefully terminate the generator
}
}
console.log(`Finished processing. Total customers processed: ${totalProcessed}`);
} catch (err) {
console.error('An error occurred during customer processing:', err.message);
}
}
// To run this in a Node.js environment, you might need a 'node-fetch' polyfill.
// In a browser, `fetch` is native.
// processCustomers(); // Uncomment to run
இந்த முறை கண்டங்கள் முழுவதும் உள்ள ஏபிஐக்களை அணுகும் உலகளாவிய பயன்பாடுகளுக்கு மிகவும் பயனுள்ளதாக இருக்கும், ஏனெனில் இது தேவைப்படும்போது மட்டுமே தரவு பெறப்படுவதை உறுதி செய்கிறது, பெரிய நினைவக அதிகரிப்புகளைத் தடுத்து, இறுதிப் பயனருக்கு உணரும் செயல்திறனை மேம்படுத்துகிறது. இது நுகர்வோரின் 'வேகத்தைக் குறைப்பதை' இயற்கையாகவே கையாளுகிறது, தயாரிப்பாளர் பக்கத்தில் ஏபிஐ வீத வரம்பு சிக்கல்களைத் தடுக்கிறது.
பெரிய கோப்புகளை வரியாகச் செயலாக்குதல்
மிகப் பெரிய கோப்புகளை (உதாரணமாக, பதிவு கோப்புகள், CSV ஏற்றுமதிகள், தரவு டம்ப்கள்) முழுமையாக நினைவகத்தில் படிப்பது நினைவகப் பற்றாக்குறை பிழைகளுக்கும் மோசமான செயல்திறனுக்கும் வழிவகுக்கும். அசிங்க் ஜெனரேட்டர்கள், குறிப்பாக நோட்.ஜேஎஸ்ஸில், கோப்புகளைத் துண்டுகளாக அல்லது வரியாகப் படிக்க வசதியாக இருக்கும், இது திறமையான, நினைவக-பாதுகாப்பான செயலாக்கத்தை அனுமதிக்கிறது.
சூழ்நிலை: மில்லியன் கணக்கான உள்ளீடுகளைக் கொண்டிருக்கக்கூடிய ஒரு விநியோகிக்கப்பட்ட அமைப்பிலிருந்து ஒரு பெரிய பதிவு கோப்பைப் பிரித்தல், முழு கோப்பையும் ரேமில் ஏற்றாமல்.
import { createReadStream } from 'fs';
import { createInterface } from 'readline';
// This example is primarily for Node.js environments
async function* readLinesFromFile(filePath) {
let lineCount = 0;
const fileStream = createReadStream(filePath, { encoding: 'utf8' });
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity // Treat all \r\n and \n as line breaks
});
try {
for await (const line of rl) {
yield line;
lineCount++;
}
} finally {
// Ensure the read stream and readline interface are properly closed
console.log(`Read ${lineCount} lines. Closing file stream.`);
rl.close();
fileStream.destroy(); // Important for releasing file descriptor
}
}
// --- Consumption Example ---
async function analyzeLogFile(logFilePath) {
let errorLogsFound = 0;
let totalLinesProcessed = 0;
console.log(`Starting analysis of ${logFilePath}...`);
try {
for await (const line of readLinesFromFile(logFilePath)) {
totalLinesProcessed++;
// Simulate some asynchronous analysis, e.g., regex matching, external API call
if (line.includes('ERROR')) {
console.log(`Found ERROR at line ${totalLinesProcessed}: ${line.substring(0, 100)}...`);
errorLogsFound++;
// Potentially save error to database or trigger alert
await new Promise(resolve => setTimeout(resolve, 1)); // Simulate async work
}
// Example: Stop early if too many errors are found
if (errorLogsFound > 50) {
console.log('Too many errors found. Stopping analysis early.');
break; // This will trigger the finally block in the generator
}
}
console.log(`\nAnalysis complete. Total lines processed: ${totalLinesProcessed}. Errors found: ${errorLogsFound}.`);
} catch (err) {
console.error('An error occurred during log file analysis:', err.message);
}
}
// To run this, you need a sample 'large-log-file.txt' or similar.
// Example of creating a dummy file for testing:
// const fs = require('fs');
// let dummyContent = '';
// for (let i = 0; i < 100000; i++) {
// dummyContent += `Log entry ${i}: This is some data.\n`;
// if (i % 1000 === 0) dummyContent += `Log entry ${i}: ERROR occurred! Critical issue.\n`;
// }
// fs.writeFileSync('large-log-file.txt', dummyContent);
// analyzeLogFile('large-log-file.txt'); // Uncomment to run
இந்த அணுகுமுறை விரிவான பதிவுகளை உருவாக்கும் அல்லது பெரிய தரவு ஏற்றுமதிகளைச் செயலாக்கும் அமைப்புகளுக்கு விலைமதிப்பற்றது, இது திறமையான நினைவகப் பயன்பாட்டை உறுதி செய்கிறது மற்றும் கணினி செயலிழப்புகளைத் தடுக்கிறது, குறிப்பாக வரையறுக்கப்பட்ட வளங்களில் செயல்படும் கிளவுட் அடிப்படையிலான சேவைகள் மற்றும் தரவு பகுப்பாய்வு தளங்களுக்குப் பொருத்தமானது.
நிகழ்நேர நிகழ்வு ஸ்ட்ரீம்கள் (உதாரணமாக, வெப்சாக்கெட்டுகள், சர்வர்-சென்ட் நிகழ்வுகள்)
நிகழ்நேரப் பயன்பாடுகள் பெரும்பாலும் நிகழ்வுகள் அல்லது செய்திகளின் தொடர்ச்சியான ஸ்ட்ரீம்களை உள்ளடக்கியிருக்கும். பாரம்பரிய நிகழ்வு கேட்பவர்கள் பயனுள்ளதாக இருந்தாலும், அசிங்க் ஜெனரேட்டர்கள் ஒரு நேரியல், தொடர்ச்சியான செயலாக்க மாதிரியை வழங்க முடியும், குறிப்பாக நிகழ்வுகளின் வரிசை முக்கியமாக இருக்கும்போது அல்லது ஸ்ட்ரீமிற்கு சிக்கலான, தொடர்ச்சியான தர்க்கம் பயன்படுத்தப்படும்போது.
சூழ்நிலை: ஒரு உலகளாவிய செய்தியிடல் பயன்பாட்டில் ஒரு வெப்சாக்கெட் இணைப்பிலிருந்து வரும் தொடர்ச்சியான அரட்டை செய்திகளைச் செயலாக்குதல்.
// This example assumes a WebSocket client library is available (e.g., 'ws' in Node.js, native WebSocket in browser)
async function* subscribeToWebSocketMessages(wsUrl) {
const ws = new WebSocket(wsUrl);
const messageQueue = [];
let resolveNextMessage = null;
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (resolveNextMessage) {
resolveNextMessage(message);
resolveNextMessage = null;
} else {
messageQueue.push(message);
}
};
ws.onopen = () => console.log(`Connected to WebSocket: ${wsUrl}`);
ws.onclose = () => console.log('WebSocket disconnected.');
ws.onerror = (error) => console.error('WebSocket error:', error.message);
try {
while (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
if (messageQueue.length > 0) {
yield messageQueue.shift();
} else {
yield new Promise(resolve => {
resolveNextMessage = resolve;
});
}
}
} finally {
if (ws.readyState === WebSocket.OPEN) {
ws.close();
}
console.log('WebSocket stream closed gracefully.');
}
}
// --- Consumption Example ---
async function processChatStream() {
const chatWsUrl = 'ws://localhost:8080/chat'; // Replace with your WebSocket server URL
let processedMessages = 0;
console.log('Starting chat message processing...');
try {
for await (const message of subscribeToWebSocketMessages(chatWsUrl)) {
console.log(`New chat message from ${message.user}: ${message.text}`);
processedMessages++;
// Simulate some async processing like sentiment analysis or storage
await new Promise(resolve => setTimeout(resolve, 20));
if (processedMessages >= 10) {
console.log('Processed 10 messages. Stopping chat stream early.');
break; // This will close the WebSocket via the finally block
}
}
} catch (err) {
console.error('Error processing chat stream:', err.message);
}
console.log('Chat stream processing finished.');
}
// Note: This example requires a WebSocket server running at ws://localhost:8080/chat.
// In a browser, `WebSocket` is global. In Node.js, you'd use a library like 'ws'.
// processChatStream(); // Uncomment to run
இந்த பயன்பாட்டு வழக்கு சிக்கலான நிகழ்நேரச் செயலாக்கத்தை எளிதாக்குகிறது, உள்வரும் நிகழ்வுகளின் அடிப்படையில் செயல்களின் வரிசைகளை ஒருங்கிணைப்பதை எளிதாக்குகிறது, இது குறிப்பாக ஊடாடும் டாஷ்போர்டுகள், ஒத்துழைப்புக் கருவிகள் மற்றும் பல்வேறு புவியியல் இருப்பிடங்களில் உள்ள IoT தரவு ஸ்ட்ரீம்களுக்குப் பயனுள்ளதாக இருக்கும்.
எல்லையற்ற தரவு மூலங்களை உருவகப்படுத்துதல்
சோதனை, மேம்பாடு அல்லது சில பயன்பாட்டு தர்க்கங்களுக்காக, காலப்போக்கில் மதிப்புகளை உருவாக்கும் ஒரு 'எல்லையற்ற' தரவு ஸ்ட்ரீம் உங்களுக்குத் தேவைப்படலாம். அசிங்க் ஜெனரேட்டர்கள் இதற்கு சரியானவை, ஏனெனில் அவை தேவைக்கேற்ப மதிப்புகளை உருவாக்குகின்றன, நினைவகத் திறனை உறுதி செய்கின்றன.
சூழ்நிலை: ஒரு கண்காணிப்பு டாஷ்போர்டு அல்லது பகுப்பாய்வுக் குழாய்க்காக உருவகப்படுத்தப்பட்ட சென்சார் வாசிப்புகளின் (உதாரணமாக, வெப்பநிலை, ஈரப்பதம்) தொடர்ச்சியான ஸ்ட்ரீமை உருவாக்குதல்.
async function* simulateSensorData() {
let id = 0;
while (true) { // An infinite loop, as values are generated on demand
const temperature = (Math.random() * 20 + 15).toFixed(2); // Between 15 and 35
const humidity = (Math.random() * 30 + 40).toFixed(2); // Between 40 and 70
const timestamp = new Date().toISOString();
yield {
id: id++,
timestamp,
temperature: parseFloat(temperature),
humidity: parseFloat(humidity)
};
// Simulate sensor reading interval
await new Promise(resolve => setTimeout(resolve, 500));
}
}
// --- Consumption Example ---
async function processSensorReadings() {
let readingsCount = 0;
console.log('Starting sensor data simulation...');
try {
for await (const data of simulateSensorData()) {
console.log(`Sensor Reading ${data.id}: Temp=${data.temperature}°C, Humidity=${data.humidity}% at ${data.timestamp}`);
readingsCount++;
if (readingsCount >= 20) {
console.log('Processed 20 sensor readings. Stopping simulation.');
break; // Terminate the infinite generator
}
}
} catch (err) {
console.error('Error processing sensor data:', err.message);
}
console.log('Sensor data processing finished.');
}
// processSensorReadings(); // Uncomment to run
இது IoT பயன்பாடுகள், முன்கணிப்புப் பராமரிப்பு அமைப்புகள் அல்லது நிகழ்நேரப் பகுப்பாய்வுத் தளங்களுக்கு யதார்த்தமான சோதனைச் சூழல்களை உருவாக்குவதற்கு விலைமதிப்பற்றது, டெவலப்பர்கள் வெளிப்புற வன்பொருள் அல்லது நேரடித் தரவு ஊற்றுகளைச் சார்ந்து இல்லாமல் தங்கள் ஸ்ட்ரீம் செயலாக்கத் தர்க்கத்தைச் சோதிக்க அனுமதிக்கிறது.
தரவு உருமாற்றக் குழாய்கள்
அசிங்க் ஜெனரேட்டர்களின் மிகவும் சக்திவாய்ந்த பயன்பாடுகளில் ஒன்று, அவற்றை ஒன்றாகச் சங்கிலிப்படுத்தி திறமையான, வாசிக்கக்கூடிய மற்றும் அதிக மட்டுப்படுத்தப்பட்ட தரவு உருமாற்றக் குழாய்களை உருவாக்குவதாகும். குழாயில் உள்ள ஒவ்வொரு ஜெனரேட்டரும் ஒரு குறிப்பிட்ட பணியைச் செய்ய முடியும் (வடிகட்டுதல், வரைபடமாக்குதல், தரவை அதிகரித்தல்), தரவைப் படிப்படியாகச் செயலாக்குதல்.
சூழ்நிலை: மூல பதிவு உள்ளீடுகளைப் பெற்று, அவற்றைப் பிழைகளுக்கு வடிகட்டி, மற்றொரு சேவையிலிருந்து பயனர் தகவலுடன் செறிவூட்டி, பின்னர் பதப்படுத்தப்பட்ட பதிவு உள்ளீடுகளை விளைவிக்கும் ஒரு குழாய்.
// Assume a simplified version of readLinesFromFile from before
// async function* readLinesFromFile(filePath) { ... yield line; ... }
// Step 1: Filter log entries for 'ERROR' messages
async function* filterErrorLogs(logStream) {
for await (const line of logStream) {
if (line.includes('ERROR')) {
yield line;
}
}
}
// Step 2: Parse log entries into structured objects
async function* parseLogEntry(errorLogStream) {
for await (const line of errorLogStream) {
const match = line.match(/ERROR.*user=(\w+).*message=(.*)/);
if (match) {
yield { user: match[1], message: match[2], raw: line };
} else {
// Yield unparsed or handle as an error
yield { user: 'unknown', message: 'unparseable', raw: line };
}
await new Promise(resolve => setTimeout(resolve, 1)); // Simulate async parsing work
}
}
// Step 3: Enrich with user details (e.g., from an external microservice)
async function* enrichWithUserDetails(parsedLogStream) {
const userCache = new Map(); // Simple cache to avoid redundant API calls
for await (const logEntry of parsedLogStream) {
let userDetails = userCache.get(logEntry.user);
if (!userDetails) {
// Simulate fetching user details from an external API
// In a real app, this would be an actual API call (e.g., await fetch(`/api/users/${logEntry.user}`))
userDetails = await new Promise(resolve => {
setTimeout(() => {
resolve({ name: `User ${logEntry.user.toUpperCase()}`, region: 'Global' });
}, 50);
});
userCache.set(logEntry.user, userDetails);
}
yield { ...logEntry, details: userDetails };
}
}
// --- Chaining and Consumption ---
async function runLogProcessingPipeline(logFilePath) {
console.log('Starting log processing pipeline...');
try {
// Assuming readLinesFromFile exists and works (e.g., from previous example)
const rawLogs = readLinesFromFile(logFilePath); // Create stream of raw lines
const errorLogs = filterErrorLogs(rawLogs); // Filter for errors
const parsedErrors = parseLogEntry(errorLogs); // Parse into objects
const enrichedErrors = enrichWithUserDetails(parsedErrors); // Add user details
let processedCount = 0;
for await (const finalLog of enrichedErrors) {
console.log(`Processed: User '${finalLog.user}' (${finalLog.details.name}, ${finalLog.details.region}) -> Message: '${finalLog.message}'`);
processedCount++;
if (processedCount >= 5) {
console.log('Processed 5 enriched logs. Stopping pipeline early.');
break;
}
}
console.log(`\nPipeline finished. Total enriched logs processed: ${processedCount}.`);
} catch (err) {
console.error('Pipeline error:', err.message);
}
}
// To test, create a dummy log file:
// const fs = require('fs');
// let dummyLogs = '';
// dummyLogs += 'INFO user=admin message=System startup\n';
// dummyLogs += 'ERROR user=john message=Failed to connect to database\n';
// dummyLogs += 'INFO user=jane message=User logged in\n';
// dummyLogs += 'ERROR user=john message=Database query timed out\n';
// dummyLogs += 'WARN user=jane message=Low disk space\n';
// dummyLogs += 'ERROR user=mary message=Permission denied on resource X\n';
// dummyLogs += 'INFO user=john message=Attempted retry\n';
// dummyLogs += 'ERROR user=john message=Still unable to connect\n';
// fs.writeFileSync('pipeline-log.txt', dummyLogs);
// runLogProcessingPipeline('pipeline-log.txt'); // Uncomment to run
இந்தக் குழாய் அணுகுமுறை அதிக மட்டுப்படுத்தப்பட்ட மற்றும் மீண்டும் பயன்படுத்தக்கூடியது. ஒவ்வொரு படியும் ஒரு சுதந்திரமான அசிங்க் ஜெனரேட்டர், இது குறியீடு மீண்டும் பயன்படுத்துவதை ஊக்குவிக்கிறது மற்றும் வெவ்வேறு தரவு செயலாக்கத் தர்க்கத்தைச் சோதிப்பதையும் இணைப்பதையும் எளிதாக்குகிறது. இந்த முன்னுதாரணம் ETL (பிரித்தெடுத்தல், உருமாற்றம், ஏற்றுதல்) செயல்முறைகள், நிகழ்நேரப் பகுப்பாய்வு மற்றும் பல்வேறு தரவு மூலங்களில் மைக்ரோ சர்வீசஸ் ஒருங்கிணைப்புக்கு விலைமதிப்பற்றது.
மேம்பட்ட வடிவங்கள் மற்றும் பரிசீலனைகள்
அசிங்க் ஜெனரேட்டர்களின் அடிப்படைப் பயன்பாடு நேரடியானது என்றாலும், அவற்றை மாஸ்டர் செய்வது வலுவான பிழை கையாளுதல், வள சுத்தம் செய்தல் மற்றும் ரத்துசெய்யும் உத்திகள் போன்ற மேம்பட்ட கருத்துக்களைப் புரிந்துகொள்வதை உள்ளடக்கியது.
அசிங்க் ஜெனரேட்டர்களில் பிழை கையாளுதல்
பிழைகள் ஜெனரேட்டருக்குள்ளும் (உதாரணமாக, ஒரு `await` அழைப்பின் போது நெட்வொர்க் தோல்வி) மற்றும் அதன் நுகர்வின் போதும் ஏற்படலாம். ஜெனரேட்டர் செயல்பாட்டிற்குள் ஒரு `try...catch` பிளாக் அதன் செயலாக்கத்தின் போது ஏற்படும் பிழைகளைப் பிடிக்க முடியும், இது ஜெனரேட்டருக்கு ஒரு பிழைச் செய்தியை விளைவிக்கவும், சுத்தம் செய்யவும் அல்லது கண்ணியமாகத் தொடரவும் அனுமதிக்கிறது.
ஒரு அசிங்க் ஜெனரேட்டருக்குள்ளிருந்து எறியப்படும் பிழைகள் நுகர்வோரின் `for await...of` லூப்பிற்குப் பரப்பப்படுகின்றன, அங்கு அவற்றை லூப்பைச் சுற்றி ஒரு நிலையான `try...catch` பிளாக்கைப் பயன்படுத்திப் பிடிக்கலாம்.
async function* reliableDataStream() {
for (let i = 0; i < 5; i++) {
try {
if (i === 2) {
throw new Error('Simulated network error at step 2');
}
yield `Data item ${i}`;
await new Promise(resolve => setTimeout(resolve, 100));
} catch (err) {
console.error(`Generator caught error: ${err.message}. Attempting to recover...`);
yield `Error notification: ${err.message}`;
// Optionally, yield a special error object, or just continue
}
}
yield 'Stream finished normally.';
}
async function consumeReliably() {
console.log('Starting reliable consumption...');
try {
for await (const item of reliableDataStream()) {
console.log(`Consumer received: ${item}`);
}
} catch (consumerError) {
console.error(`Consumer caught unhandled error: ${consumerError.message}`);
}
console.log('Reliable consumption finished.');
}
// consumeReliably(); // Uncomment to run
மூடுதல் மற்றும் வள சுத்தம் செய்தல்
அசிங்க் ஜெனரேட்டர்கள், ஒத்திசைவானவற்றைப் போலவே, ஒரு `finally` பிளாக்கைக் கொண்டிருக்கலாம். இந்த பிளாக் ஜெனரேட்டர் சாதாரணமாக முடிந்தாலோ (எல்லா `yield`களும் தீர்ந்துவிட்டாலோ), ஒரு `return` கூற்று எதிர்கொள்ளப்பட்டாலோ, அல்லது நுகர்வோர் `for await...of` லூப்பிலிருந்து வெளியேறினாலோ (உதாரணமாக, `break`, `return` ஐப் பயன்படுத்தி, அல்லது ஒரு பிழை எறியப்பட்டு ஜெனரேட்டரால் பிடிக்கப்படாவிட்டால்) இயக்கப்படுவது உறுதி. இது கோப்பு கையாளுதல்கள், தரவுத்தள இணைப்புகள் அல்லது நெட்வொர்க் சாக்கெட்டுகள் போன்ற வளங்களை நிர்வகிக்க ஏற்றதாக ஆக்குகிறது, அவை சரியாக மூடப்படுவதை உறுதி செய்கிறது.
async function* fetchDataWithCleanup(url) {
let connection;
try {
console.log(`Opening connection for ${url}...`);
// Simulate opening a connection
connection = { id: Math.random().toString(36).substring(7) };
await new Promise(resolve => setTimeout(resolve, 500));
console.log(`Connection ${connection.id} opened.`);
for (let i = 0; i < 3; i++) {
yield `Data chunk ${i} from ${url}`;
await new Promise(resolve => setTimeout(resolve, 200));
}
} finally {
if (connection) {
// Simulate closing the connection
console.log(`Closing connection ${connection.id}...`);
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Connection ${connection.id} closed.`);
}
}
}
async function testCleanup() {
console.log('Starting test cleanup...');
try {
const dataStream = fetchDataWithCleanup('http://example.com/data');
let count = 0;
for await (const item of dataStream) {
console.log(`Received: ${item}`);
count++;
if (count === 2) {
console.log('Stopping early after 2 items...');
break; // This will trigger the finally block in the generator
}
}
} catch (err) {
console.error('Error during consumption:', err.message);
}
console.log('Test cleanup finished.');
}
// testCleanup(); // Uncomment to run
ரத்துசெய்தல் மற்றும் காலக்கெடு
ஜெனரேட்டர்கள் நுகர்வோரில் `break` அல்லது `return` வழியாக கண்ணியமான முடிவை இயல்பாக ஆதரிக்கும் அதே வேளையில், வெளிப்படையான ரத்துசெய்தலை (உதாரணமாக, ஒரு `AbortController` வழியாக) செயல்படுத்துவது ஜெனரேட்டரின் செயலாக்கத்தின் மீது வெளிப்புறக் கட்டுப்பாட்டை அனுமதிக்கிறது, இது நீண்டகால செயல்பாடுகள் அல்லது பயனர்-தொடங்கிய ரத்துசெய்தல்களுக்கு முக்கியமானது.
async function* longRunningTask(signal) {
let counter = 0;
try {
while (true) {
if (signal && signal.aborted) {
console.log('Task cancelled by signal!');
return; // Exit the generator gracefully
}
yield `Processing item ${counter++}`;
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate work
}
} finally {
console.log('Long running task cleanup complete.');
}
}
async function runCancellableTask() {
const abortController = new AbortController();
const { signal } = abortController;
console.log('Starting cancellable task...');
setTimeout(() => {
console.log('Triggering cancellation in 2.2 seconds...');
abortController.abort(); // Cancel the task
}, 2200);
try {
for await (const item of longRunningTask(signal)) {
console.log(item);
}
} catch (err) {
// Errors from AbortController might not propagate directly as 'aborted' is checked
console.error('An unexpected error occurred during consumption:', err.message);
}
console.log('Cancellable task finished.');
}
// runCancellableTask(); // Uncomment to run
செயல்திறன் தாக்கங்கள்
அசிங்க் ஜெனரேட்டர்கள் ஸ்ட்ரீம் செயலாக்கத்திற்கு அதிக நினைவகத் திறன் கொண்டவை, ஏனெனில் அவை தரவைப் படிப்படியாகச் செயலாக்குகின்றன, முழுத் தரவுத்தொகுப்புகளையும் நினைவகத்தில் ஏற்ற வேண்டிய தேவையைத் தவிர்க்கின்றன. இருப்பினும், `yield` மற்றும் `next()` அழைப்புகளுக்கு இடையில் சூழல் மாறுதலின் மேல்நிலை (ஒவ்வொரு படிக்கும் குறைவாக இருந்தாலும்) மிகவும் உகந்த நேட்டிவ் ஸ்ட்ரீம் செயலாக்கங்களுடன் ஒப்பிடும்போது (நோட்.ஜேஎஸ்ஸின் நேட்டிவ் ஸ்ட்ரீம்கள் அல்லது வெப் ஸ்ட்ரீம்ஸ் ஏபிஐ போன்றவை) மிக அதிக செயல்திறன், குறைந்த தாமத சூழ்நிலைகளில் சேரலாம். பெரும்பாலான பொதுவான பயன்பாட்டு நிகழ்வுகளுக்கு, வாசிப்புத்திறன், பராமரிப்புத்திறன் மற்றும் பின்தள்ளல் மேலாண்மை ஆகியவற்றில் அவற்றின் நன்மைகள் இந்த சிறிய மேல்நிலையை விட அதிகமாக உள்ளன.
நவீன கட்டமைப்புகளில் அசிங்க் ஜெனரேட்டர்களை ஒருங்கிணைத்தல்
அசிங்க் ஜெனரேட்டர்களின் பல்துறைத்திறன் அவற்றை ஒரு நவீன மென்பொருள் சூழல் அமைப்பின் வெவ்வேறு பகுதிகளில் மதிப்புமிக்கதாக ஆக்குகிறது.
பின்தள மேம்பாடு (நோட்.ஜேஎஸ்)
- தரவுத்தள வினவல் ஸ்ட்ரீமிங்: OOM பிழைகள் இல்லாமல் ஒரு தரவுத்தளத்திலிருந்து மில்லியன் கணக்கான பதிவுகளைப் பெறுதல். அசிங்க் ஜெனரேட்டர்கள் தரவுத்தள கர்சர்களைச் சுற்றலாம்.
- பதிவு செயலாக்கம் மற்றும் பகுப்பாய்வு: பல்வேறு மூலங்களிலிருந்து சேவையகப் பதிவுகளின் நிகழ்நேர உட்கொள்ளல் மற்றும் பகுப்பாய்வு.
- ஏபிஐ கலவை: பல மைக்ரோ சர்வீஸ்களிலிருந்து தரவை ஒருங்கிணைத்தல், அங்கு ஒவ்வொரு மைக்ரோ சர்வீஸும் ஒரு பக்கப்படுத்தப்பட்ட அல்லது ஸ்ட்ரீம் செய்யக்கூடிய பதிலைத் திருப்பி அனுப்பலாம்.
- சர்வர்-சென்ட் நிகழ்வுகள் (SSE) வழங்குநர்கள்: வாடிக்கையாளர்களுக்குப் படிப்படியாகத் தரவை உந்தும் SSE இறுதிப்புள்ளிகளை எளிதாகச் செயல்படுத்தலாம்.
முன்பக்க மேம்பாடு (உலாவி)
- படிப்படியான தரவு ஏற்றுதல்: ஒரு பக்கப்படுத்தப்பட்ட ஏபிஐயிலிருந்து தரவு வரும்போது பயனர்களுக்குக் காண்பித்தல், உணரும் செயல்திறனை மேம்படுத்துதல்.
- நிகழ்நேர டாஷ்போர்டுகள்: நேரடிப் புதுப்பிப்புகளுக்கு வெப்சாக்கெட் அல்லது SSE ஸ்ட்ரீம்களைப் பயன்படுத்துதல்.
- பெரிய கோப்பு பதிவேற்றங்கள்/பதிவிறக்கங்கள்: அனுப்புவதற்கு முன்/பெற்ற பிறகு வாடிக்கையாளர் பக்கத்தில் கோப்புத் துண்டுகளைச் செயலாக்குதல், வெப் ஸ்ட்ரீம்ஸ் ஏபிஐ ஒருங்கிணைப்புடன் சாத்தியமாகும்.
- பயனர் உள்ளீட்டு ஸ்ட்ரீம்கள்: UI நிகழ்வுகளிலிருந்து ஸ்ட்ரீம்களை உருவாக்குதல் (உதாரணமாக, 'நீங்கள் தட்டச்சு செய்யும் போது தேடல்' செயல்பாடு, டிபவுன்சிங்/த்ராட்லிங்).
வலைக்கு அப்பால்: CLI கருவிகள், தரவு செயலாக்கம்
- கட்டளை-வரிப் பயன்பாடுகள்: பெரிய உள்ளீடுகளைச் செயலாக்கும் அல்லது பெரிய வெளியீடுகளை உருவாக்கும் திறமையான CLI கருவிகளை உருவாக்குதல்.
- ETL (பிரித்தெடுத்தல், உருமாற்றம், ஏற்றுதல்) ஸ்கிரிப்டுகள்: தரவு இடம்பெயர்வு, உருமாற்றம் மற்றும் உட்கொள்ளல் குழாய்களுக்கு, மட்டுப்படுத்தல் மற்றும் திறனை வழங்குகிறது.
- IoT தரவு உட்கொள்ளல்: செயலாக்கம் மற்றும் சேமிப்பிற்காக சென்சார்கள் அல்லது சாதனங்களிலிருந்து தொடர்ச்சியான ஸ்ட்ரீம்களைக் கையாளுதல்.
வலுவான அசிங்க் ஜெனரேட்டர்களை எழுதுவதற்கான சிறந்த நடைமுறைகள்
அசிங்க் ஜெனரேட்டர்களின் நன்மைகளை அதிகரிக்கவும் பராமரிக்கக்கூடிய குறியீட்டை எழுதவும், இந்த சிறந்த நடைமுறைகளைக் கருத்தில் கொள்ளுங்கள்:
- ஒற்றைப் பொறுப்புக் கொள்கை (SRP): ஒவ்வொரு அசிங்க் ஜெனரேட்டரையும் ஒரு ஒற்றை, நன்கு வரையறுக்கப்பட்ட பணியைச் செய்ய வடிவமைக்கவும் (உதாரணமாக, பெறுதல், பிரித்தல், வடிகட்டுதல்). இது மட்டுப்படுத்தல் மற்றும் மீண்டும் பயன்படுத்துவதை ஊக்குவிக்கிறது.
- கண்ணியமான பிழை கையாளுதல்: எதிர்பார்க்கப்படும் பிழைகளைக் கையாள (உதாரணமாக, நெட்வொர்க் சிக்கல்கள்) ஜெனரேட்டருக்குள் `try...catch` பிளாக்குகளைச் செயல்படுத்தவும், அது தொடர அல்லது அர்த்தமுள்ள பிழை பேலோடுகளை வழங்க அனுமதிக்கவும். நுகர்வோரும் அதன் `for await...of` லூப்பைச் சுற்றி `try...catch` வைத்திருப்பதை உறுதி செய்யவும்.
- சரியான வள சுத்தம் செய்தல்: உங்கள் அசிங்க் ஜெனரேட்டர்களுக்குள் எப்போதும் `finally` பிளாக்குகளைப் பயன்படுத்தவும், நுகர்வோர் முன்கூட்டியே நிறுத்தப்பட்டாலும் வளங்கள் (கோப்பு கையாளுதல்கள், நெட்வொர்க் இணைப்புகள்) வெளியிடப்படுவதை உறுதி செய்யவும்.
- தெளிவான பெயரிடல்: உங்கள் அசிங்க் ஜெனரேட்டர் செயல்பாடுகளுக்கு அவற்றின் நோக்கத்தையும் அவை எந்த வகையான ஸ்ட்ரீமை உருவாக்குகின்றன என்பதையும் தெளிவாகக் குறிக்கும் விளக்கமான பெயர்களைப் பயன்படுத்தவும்.
- நடத்தையை ஆவணப்படுத்துங்கள்: எதிர்பார்க்கப்படும் உள்ளீட்டு ஸ்ட்ரீம்கள், பிழை நிலைகள் அல்லது வள மேலாண்மைத் தாக்கங்கள் போன்ற எந்தவொரு குறிப்பிட்ட நடத்தைகளையும் தெளிவாக ஆவணப்படுத்துங்கள்.
- 'பிரேக்' நிபந்தனைகள் இல்லாமல் எல்லையற்ற லூப்களைத் தவிர்க்கவும்: நீங்கள் ஒரு எல்லையற்ற ஜெனரேட்டரை (`while(true)`) வடிவமைத்தால், நுகர்வோர் அதை முடிக்க ஒரு தெளிவான வழி இருப்பதை உறுதி செய்யவும் (உதாரணமாக, `break`, `return`, அல்லது `AbortController` வழியாக).
- பிரதிநிதித்துவத்திற்கு `yield*` ஐக் கருத்தில் கொள்ளுங்கள்: ஒரு அசிங்க் ஜெனரேட்டர் மற்றொரு அசிங்க் இட்டரேபிளிலிருந்து எல்லா மதிப்புகளையும் விளைவிக்க வேண்டியிருக்கும் போது, `yield*` என்பது பிரதிநிதித்துவம் செய்ய ஒரு சுருக்கமான மற்றும் திறமையான வழியாகும்.
ஜாவாஸ்கிரிப்ட் ஸ்ட்ரீம்கள் மற்றும் அசிங்க் ஜெனரேட்டர்களின் எதிர்காலம்
ஜாவாஸ்கிரிப்டில் ஸ்ட்ரீம் செயலாக்கத்தின் நிலப்பரப்பு தொடர்ந்து உருவாகி வருகிறது. வெப் ஸ்ட்ரீம்ஸ் ஏபிஐ (ReadableStream, WritableStream, TransformStream) என்பது உயர்-செயல்திறன் ஸ்ட்ரீம்களை உருவாக்குவதற்கான ஒரு சக்திவாய்ந்த, குறைந்த-நிலை அடிப்படை ஆகும், இது நவீன உலாவிகளிலும் மற்றும் நோட்.ஜேஎஸ்ஸிலும் பெருகிய முறையில் கிடைக்கிறது. அசிங்க் ஜெனரேட்டர்கள் வெப் ஸ்ட்ரீம்களுடன் இயல்பாகவே இணக்கமாக உள்ளன, ஏனெனில் ஒரு `ReadableStream` ஒரு அசிங்க் இட்டரேட்டரிலிருந்து கட்டமைக்கப்படலாம், இது தடையற்ற இயங்குதன்மையை அனுமதிக்கிறது.
இந்த ஒத்திசைவு டெவலப்பர்கள் அசிங்க் ஜெனரேட்டர்களின் பயன்பாட்டின் எளிமை மற்றும் இழுத்தல்-அடிப்படையிலான சொற்பொருள்களைப் பயன்படுத்தித் தனிப்பயன் ஸ்ட்ரீம் மூலங்கள் மற்றும் உருமாற்றங்களை உருவாக்கலாம், பின்னர் அவற்றை குழாய்வழி, பின்தள்ளல் கட்டுப்பாடு மற்றும் பைனரி தரவைத் திறமையாகக் கையாளுதல் போன்ற மேம்பட்ட சூழ்நிலைகளுக்கு பரந்த வெப் ஸ்ட்ரீம்ஸ் சூழல் அமைப்புடன் ஒருங்கிணைக்கலாம். எதிர்காலம் சிக்கலான தரவு ஓட்டங்களை நிர்வகிக்க இன்னும் வலுவான மற்றும் டெவலப்பர்-நட்பு வழிகளை உறுதியளிக்கிறது, அசிங்க் ஜெனரேட்டர்கள் நெகிழ்வான, உயர்-நிலை ஸ்ட்ரீம் உருவாக்க உதவியாளர்களாக ஒரு மையப் பாத்திரத்தை வகிக்கின்றன.
முடிவுரை: அசிங்க் ஜெனரேட்டர்களுடன் ஸ்ட்ரீம்-இயங்கும் எதிர்காலத்தைத் தழுவுங்கள்
ஜாவாஸ்கிரிப்ட்டின் அசிங்க் ஜெனரேட்டர்கள் ஒத்திசைவற்ற தரவை நிர்வகிப்பதில் ஒரு குறிப்பிடத்தக்க முன்னேற்றத்தைக் குறிக்கின்றன. அவை இழுத்தல்-அடிப்படையிலான ஸ்ட்ரீம்களை உருவாக்குவதற்கான ஒரு சுருக்கமான, வாசிக்கக்கூடிய மற்றும் அதிக திறமையான வழிமுறையை வழங்குகின்றன, அவற்றை பெரிய தரவுத்தொகுப்புகள், நிகழ்நேர நிகழ்வுகள் மற்றும் தொடர்ச்சியான, நேரத்தைச் சார்ந்த தரவு ஓட்டத்தை உள்ளடக்கிய எந்தவொரு சூழ்நிலைக்கும் ഒഴിച്ചുകൂടാനാവാത്ത கருவிகளாக ஆக்குகின்றன. அவற்றின் உள்ளார்ந்த பின்தள்ளல் பொறிமுறை, வலுவான பிழை கையாளுதல் மற்றும் வள மேலாண்மைத் திறன்களுடன் இணைந்து, செயல்திறன் மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கான ஒரு மூலக்கல்லாக அவற்றை நிலைநிறுத்துகிறது.
உங்கள் மேம்பாட்டுப் பணிப்பாய்வில் அசிங்க் ஜெனரேட்டர்களை ஒருங்கிணைப்பதன் மூலம், நீங்கள் பாரம்பரிய ஒத்திசைவற்ற வடிவங்களைத் தாண்டிச் செல்லலாம், புதிய அளவிலான நினைவகத் திறனைத் திறக்கலாம், மற்றும் நவீன டிஜிட்டல் உலகை வரையறுக்கும் தொடர்ச்சியான தகவல் ஓட்டத்தை கண்ணியமாகக் கையாளக்கூடிய உண்மையான பதிலளிக்கக்கூடிய பயன்பாடுகளை உருவாக்கலாம். இன்று அவற்றுடன் பரிசோதனை செய்யத் தொடங்குங்கள், மற்றும் அவை உங்கள் தரவு செயலாக்கம் மற்றும் பயன்பாட்டுக் கட்டமைப்புக்கான அணுகுமுறையை எவ்வாறு மாற்றியமைக்க முடியும் என்பதைக் கண்டறியுங்கள்.