JavaScript Async Generatorlarini samarali oqimni qayta ishlash uchun o'rganing. Asinxron ma'lumotlarni boshqarish uchun ilg'or naqshlarni yaratish, iste'mol qilish va amalga oshirishni o'rganing.
JavaScript Async Generatorlari: Oqimni qayta ishlash naqshlarini o'zlashtirish
JavaScript Async Generatorlari asinxron ma'lumot oqimlarini samarali boshqarish uchun kuchli mexanizmni taqdim etadi. Ular asinxron dasturlash qobiliyatlarini iteratorlarning nafisligi bilan birlashtirib, ma'lumotlarni asosiy ipni bloklamasdan, mavjud bo'lganda qayta ishlash imkonini beradi. Bu yondashuv katta ma'lumotlar to'plamlari, real vaqtda ma'lumotlar oqimlari va murakkab ma'lumotlarni o'zgartirish bilan bog'liq stsenariylar uchun ayniqsa foydalidir.
Async Generatorlar va Async Iteratorlarni tushunish
Oqimni qayta ishlash naqshlariga sho'ng'ishdan oldin, Async Generatorlar va Async Iteratorlarning asosiy tushunchalarini tushunish juda muhimdir.
Async Generatorlar nima?
Async Generator - to'xtatilishi va qayta boshlanishi mumkin bo'lgan, asinxron qiymatlarni berishga imkon beruvchi maxsus turdagi funksiya. U async function*
sintaksisi yordamida aniqlanadi. Oddiy generatorlardan farqli o'laroq, Async Generatorlar generator funksiyasida asinxron operatsiyalarni boshqarish uchun await
-dan foydalanishi mumkin.
Misol:
async function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Asinxron kechikishni simulyatsiya qilish
yield i;
}
}
Ushbu misolda, generateSequence
- start
-dan end
-gacha bo'lgan sonlar ketma-ketligini beradigan Async Generator, har bir son o'rtasida 500ms kechikish bilan. await
kalit so'zi generatorning va'da hal qilinmaguncha to'xtashini ta'minlaydi (asinxron operatsiyani simulyatsiya qilish).
Async Iteratorlar nima?
Async Iterator - Async Iterator protokoliga mos keladigan ob'ekt. U next()
usuliga ega bo'lib, va'dani qaytaradi. Va'da hal qilinganda, u ikkita xususiyatga ega bo'lgan ob'ektni taqdim etadi: value
(berilgan qiymat) va done
(iterator ketma-ketlik oxiriga yetganligini ko'rsatuvchi mantiqiy qiymat).
Async Generatorlar avtomatik ravishda Async Iteratorlarni yaratadi. Siz for await...of
tsikli yordamida Async Generatordan olingan qiymatlar bo'yicha iteratsiya qilishingiz mumkin.
Misol:
async function consumeSequence() {
for await (const num of generateSequence(1, 5)) {
console.log(num);
}
}
consumeSequence(); // Output: 1 (after 500ms), 2 (after 1000ms), 3 (after 1500ms), 4 (after 2000ms), 5 (after 2500ms)
for await...of
tsikli generateSequence
Async Generator tomonidan berilgan qiymatlar bo'yicha asinxron iteratsiya qiladi, har bir raqamni konsolga chop etadi.
Async Generatorlar bilan oqimni qayta ishlash naqshlari
Async Generatorlar turli xil oqimlarni qayta ishlash naqshlarini amalga oshirish uchun juda ko'p qirrali. Mana ba'zi umumiy va kuchli naqshlar:
1. Ma'lumotlar manbasini abstraktlash
Async Generatorlar turli ma'lumotlar manbalarining murakkabligini olib tashlashi, ma'lumotlarga uning kelib chiqishidan qat'iy nazar kirish uchun yagona interfeysni taqdim etishi mumkin. Bu API, ma'lumotlar bazalari yoki fayl tizimlari bilan ishlashda ayniqsa foydalidir.
Misol: API dan ma'lumotlarni olish
async function* fetchUsers(apiUrl) {
let page = 1;
while (true) {
const url = `${apiUrl}?page=${page}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.length === 0) {
return; // Boshqa ma'lumot yo'q
}
for (const user of data) {
yield user;
}
page++;
}
}
async function processUsers() {
const userGenerator = fetchUsers('https://api.example.com/users'); // API oxirgi nuqtangiz bilan almashtiring
for await (const user of userGenerator) {
console.log(user.name);
// Har bir foydalanuvchini qayta ishlash
}
}
processUsers();
Ushbu misolda, fetchUsers
Async Generator foydalanuvchilarni API oxirgi nuqtasidan oladi, sahifalashni avtomatik ravishda boshqaradi. processUsers
funksiyasi ma'lumotlar oqimini iste'mol qiladi va har bir foydalanuvchini qayta ishlaydi.
Xalqaro tilga tarjima qilish bo'yicha eslatma: API-dan ma'lumotlarni olishda, butun dunyo bo'ylab foydalanuvchilar uchun izchil tajriba taqdim etish uchun API oxirgi nuqtasi xalqarolashtirish standartlariga (masalan, til kodlari va mintaqaviy sozlamalarni qo'llab-quvvatlash) rioya qilishini ta'minlang.
2. Ma'lumotlarni o'zgartirish va filtrlash
Async Generatorlar asosiy ipni bloklamasdan, asinxron tarzda o'zgartirishlarni qo'llash orqali ma'lumotlar oqimlarini o'zgartirish va filtrlash uchun ishlatilishi mumkin.
Misol: Jurnal yozuvlarini filtrlash va o'zgartirish
async function* filterAndTransformLogs(logGenerator, filterKeyword) {
for await (const logEntry of logGenerator) {
if (logEntry.message.includes(filterKeyword)) {
const transformedEntry = {
timestamp: logEntry.timestamp,
level: logEntry.level,
message: logEntry.message.toUpperCase(),
};
yield transformedEntry;
}
}
}
async function* readLogsFromFile(filePath) {
// Fayldan jurnallarni asinxron ravishda o'qishni simulyatsiya qilish
const logs = [
{ timestamp: '2024-01-01T00:00:00', level: 'INFO', message: 'System started' },
{ timestamp: '2024-01-01T00:00:05', level: 'WARN', message: 'Low memory warning' },
{ timestamp: '2024-01-01T00:00:10', level: 'ERROR', message: 'Database connection failed' },
];
for (const log of logs) {
await new Promise(resolve => setTimeout(resolve, 100)); // Asinxron o'qishni simulyatsiya qilish
yield log;
}
}
async function processFilteredLogs() {
const logGenerator = readLogsFromFile('logs.txt');
const filteredLogs = filterAndTransformLogs(logGenerator, 'ERROR');
for await (const log of filteredLogs) {
console.log(log);
}
}
processFilteredLogs();
Ushbu misolda, filterAndTransformLogs
jurnal yozuvlarini kalit so'zga asoslanib filtrlash va mos yozuvlarni katta harflarga o'zgartiradi. readLogsFromFile
funksiyasi jurnal yozuvlarini fayldan asinxron ravishda o'qishni simulyatsiya qiladi.
3. Bir vaqtning o'zida qayta ishlash
Async Generatorlar hisoblash jihatidan intensiv vazifalar uchun ishlashni yaxshilash uchun Promise.all
yoki shunga o'xshash bir vaqtning o'zida ishlash mexanizmlari bilan birlashtirilishi mumkin.
Misol: Tasvirlarni bir vaqtning o'zida qayta ishlash
async function* generateImagePaths(imageUrls) {
for (const url of imageUrls) {
yield url;
}
}
async function processImage(imageUrl) {
// Tasvirni qayta ishlashni simulyatsiya qilish
await new Promise(resolve => setTimeout(resolve, 200));
console.log(`Qayta ishlangan rasm: ${imageUrl}`);
return `Qayta ishlangan: ${imageUrl}`;
}
async function processImagesConcurrently(imageUrls, concurrencyLimit) {
const imageGenerator = generateImagePaths(imageUrls);
const processingPromises = [];
async function processNextImage() {
const { value, done } = await imageGenerator.next();
if (done) {
return;
}
const processingPromise = processImage(value);
processingPromises.push(processingPromise);
processingPromise.finally(() => {
// Tugallangan va'dani massivdan olib tashlang
processingPromises.splice(processingPromises.indexOf(processingPromise), 1);
// Agar iloji bo'lsa, keyingi tasvirni qayta ishlashni boshlang
if (processingPromises.length < concurrencyLimit) {
processNextImage();
}
});
if (processingPromises.length < concurrencyLimit) {
processNextImage();
}
}
// Dastlabki bir vaqtning o'zida jarayonlarni boshlang
for (let i = 0; i < concurrencyLimit && i < imageUrls.length; i++) {
processNextImage();
}
// Qaytishdan oldin barcha va'dalarning hal qilinishini kuting
await Promise.all(processingPromises);
console.log('Barcha rasmlar qayta ishlandi.');
}
const imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg',
'https://example.com/image4.jpg',
'https://example.com/image5.jpg',
];
processImagesConcurrently(imageUrls, 2);
Ushbu misolda, generateImagePaths
tasvir URL-larining oqimini beradi. processImage
funksiyasi tasvirni qayta ishlashni simulyatsiya qiladi. processImagesConcurrently
tasvirlarni bir vaqtning o'zida qayta ishlaydi, bir vaqtning o'zida jarayonlar sonini 2 taga, va'da massivi yordamida cheklaydi. Bu tizimni haddan tashqari ko'payishining oldini olish uchun muhimdir. Har bir rasm asinxron tarzda setTimeout orqali qayta ishlanadi. Nihoyat, Promise.all
barcha jarayonlar umumiy operatsiyani tugatishdan oldin tugashini ta'minlaydi.
4. Orqa bosimni boshqarish
Orqa bosim - oqimni qayta ishlashda, ayniqsa ma'lumot ishlab chiqarish tezligi ma'lumot iste'mol qilish tezligidan oshib ketganda muhim tushuncha. Async Generatorlar iste'molchini haddan tashqari ko'payishining oldini olib, orqa bosim mexanizmlarini amalga oshirish uchun ishlatilishi mumkin.
Misol: Tezlik cheklovchini amalga oshirish
async function* applyRateLimit(dataGenerator, interval) {
for await (const data of dataGenerator) {
await new Promise(resolve => setTimeout(resolve, interval));
yield data;
}
}
async function* generateData() {
let i = 0;
while (true) {
await new Promise(resolve => setTimeout(resolve, 10)); // Tez ishlab chiqaruvchini simulyatsiya qilish
yield `Ma'lumotlar ${i++}`;
}
}
async function consumeData() {
const dataGenerator = generateData();
const rateLimitedData = applyRateLimit(dataGenerator, 500); // Har 500ms da bir elementgacha cheklash
for await (const data of rateLimitedData) {
console.log(data);
}
}
// consumeData(); // Ehtiyot bo'ling, bu cheksiz davom etadi
Ushbu misolda, applyRateLimit
ma'lumotlarning dataGenerator
dan olinadigan tezligini cheklaydi, iste'molchi uni qayta ishlay oladiganidan tezroq ma'lumot olmasligini ta'minlaydi.
5. Oqimlarni birlashtirish
Async Generatorlar murakkab ma'lumotlar quvurlarini yaratish uchun birlashtirilishi mumkin. Bu bir nechta manbalardan ma'lumotlarni birlashtirish, murakkab transformatsiyalarni bajarish yoki filial ma'lumotlar oqimlarini yaratish uchun foydali bo'lishi mumkin.
Misol: Ikki API dan ma'lumotlarni birlashtirish
async function* mergeStreams(stream1, stream2) {
const iterator1 = stream1();
const iterator2 = stream2();
let next1 = iterator1.next();
let next2 = iterator2.next();
while (!((await next1).done && (await next2).done)) {
if (!(await next1).done) {
yield (await next1).value;
next1 = iterator1.next();
}
if (!(await next2).done) {
yield (await next2).value;
next2 = iterator2.next();
}
}
}
async function* generateNumbers(limit) {
for (let i = 1; i <= limit; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
async function* generateLetters(limit) {
const letters = 'abcdefghijklmnopqrstuvwxyz';
for (let i = 0; i < limit; i++) {
await new Promise(resolve => setTimeout(resolve, 150));
yield letters[i];
}
}
async function processMergedData() {
const numberStream = () => generateNumbers(5);
const letterStream = () => generateLetters(3);
const mergedStream = mergeStreams(numberStream, letterStream);
for await (const item of mergedStream) {
console.log(item);
}
}
processMergedData();
Ushbu misolda, mergeStreams
o'z chiqishini qatorma-qator joylashtirib, ikkita Async Generator funksiyasidan ma'lumotlarni birlashtiradi. generateNumbers
va generateLetters
- mos ravishda raqamli va alifbo ma'lumotlarini taqdim etuvchi namunaviy Async Generatorlar.
Ilg'or usullar va e'tiborga olinadigan jihatlar
Async Generatorlar asinxron oqimlarni boshqarishning kuchli usulini taklif qilsa-da, ba'zi ilg'or texnikalar va potentsial qiyinchiliklarni ko'rib chiqish muhimdir.
Xatolarni boshqarish
Asinxron kodda to'g'ri xatolarni boshqarish juda muhimdir. Xatolarni muloyimlik bilan boshqarish uchun Async Generatorlar ichida try...catch
bloklaridan foydalanishingiz mumkin.
async function* safeGenerator() {
try {
// Xatolarni keltirib chiqarishi mumkin bo'lgan asinxron operatsiyalar
const data = await fetchData();
yield data;
} catch (error) {
console.error('Generator ichidagi xatolik:', error);
// Ixtiyoriy ravishda xato qiymatini bering yoki generatorni to'xtating
yield { error: error.message };
return; // Generatorni to'xtating
}
}
Bekor qilish
Ba'zi hollarda, siz davom etayotgan asinxron operatsiyani bekor qilishingiz kerak bo'lishi mumkin. Bu AbortController kabi usullar yordamida amalga oshirilishi mumkin.
async function* fetchWithCancellation(url, signal) {
try {
const response = await fetch(url, { signal });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
yield data;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Olish bekor qilindi');
return;
}
throw error;
}
}
const controller = new AbortController();
const { signal } = controller;
async function consumeData() {
const dataGenerator = fetchWithCancellation('https://api.example.com/data', signal); // API oxirgi nuqtangiz bilan almashtiring
setTimeout(() => {
controller.abort(); // 2 soniyadan so'ng olishni bekor qiling
}, 2000);
try {
for await (const data of dataGenerator) {
console.log(data);
}
} catch (error) {
console.error('Iste'mol paytida xatolik:', error);
}
}
consumeData();
Xotirani boshqarish
Katta ma'lumot oqimlari bilan ishlashda xotirani samarali boshqarish muhimdir. Bir vaqtning o'zida katta hajmdagi ma'lumotlarni xotirada saqlashdan saqlaning. Async Generatorlar, o'z tabiati bilan, ma'lumotlarni bo'laklarda qayta ishlash orqali bu borada yordam beradi.
Debaglash
Asinxron kodni debaglash qiyin bo'lishi mumkin. Kodingiz bo'yicha qadam qo'yish va o'zgaruvchilarni tekshirish uchun brauzer ishlab chiquvchi vositalaridan yoki Node.js debaglardan foydalaning.
Haqiqiy dunyo ilovalari
Async Generatorlar ko'plab real hayotdagi stsenariylarda qo'llaniladi:
- Real vaqtda ma'lumotlarni qayta ishlash: Veb-socketlar yoki server tomonidan yuborilgan voqealardan (SSE) ma'lumotlarni qayta ishlash.
- Katta fayllarni qayta ishlash: Katta fayllarni bo'laklarda o'qish va qayta ishlash.
- Ma'lumotlar bazalaridan ma'lumotlarni oqimlash: Barcha ma'lumotlarni bir vaqtning o'zida xotiraga yuklamasdan, ma'lumotlar bazalaridan katta ma'lumotlar to'plamlarini olish va qayta ishlash.
- API ma'lumotlarini jamlash: Yagona ma'lumotlar oqimini yaratish uchun bir nechta API-dan ma'lumotlarni birlashtirish.
- ETL (Olish, O'zgartirish, Yuklash) quvurlari: Ma'lumotlar omborlari va analitikalar uchun murakkab ma'lumotlar quvurlarini yaratish.
Misol: Katta CSV faylini qayta ishlash (Node.js)
const fs = require('fs');
const readline = require('readline');
async function* readCSV(filePath) {
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity,
});
for await (const line of rl) {
// Har bir satrni CSV yozuvi sifatida qayta ishlash
const record = line.split(',');
yield record;
}
}
async function processCSV() {
const csvGenerator = readCSV('large_data.csv');
for await (const record of csvGenerator) {
// Har bir yozuvni qayta ishlash
console.log(record);
}
}
// processCSV();
Xulosa
JavaScript Async Generatorlari asinxron ma'lumot oqimlarini boshqarishning kuchli va nafis usulini taklif etadi. Ma'lumotlar manbasini abstraktlash, o'zgartirish, bir vaqtning o'zida ishlash, orqa bosim va oqimni birlashtirish kabi oqimni qayta ishlash naqshlarini o'zlashtirish orqali siz katta ma'lumotlar to'plamlari va real vaqtda ma'lumot oqimlarini samarali boshqaradigan samarali va masshtabli ilovalarni yaratishingiz mumkin. Xatolarni boshqarish, bekor qilish, xotirani boshqarish va debaglash texnikasini tushunish Async Generatorlar bilan ishlash qobiliyatingizni yanada oshiradi. Asinxron dasturlash tobora keng tarqalmoqda, Async Generatorlar zamonaviy JavaScript dasturchilari uchun qimmatli vositalar to'plamini taqdim etadi.
JavaScript loyihalaringizda asinxron ma'lumotlarni qayta ishlashning to'liq salohiyatini ochish uchun Async Generatorlardan foydalaning.