რატომ შეუძლიათ ჩვეულებრივ გენერატორებს ასინქრონული კოდის დაწერა?
sobes.tech AI
პასუხი AI-სგან
JavaScript-те гадәтиген генераторлар асинхрон код жазууга мүмкүндүк берет, алардын токтоп жана кайра жандануу жөндөмү жана эки тараптуу маанилерди өткөрүү мүмкүнчүлүгү (yield жана next()).
Мына, бул асинхрондуктун контекстинде кандай иштейт:
-
Иштөөнү токтотуу (
yield):yieldоператоруна жеткенде, генератор токтоп, маанини кайтарат. Асинхрон коддо, бул мааниге промис же башка "иш" кириши мүмкүн, аны асинхрон түрдө аткаруу керек. -
Асинхрон жыйынтыкты күтүү: Чыгаргы код (мисалы, "жүгүргүч" же генератор үчүн капталган)
yieldаркылуу берилген маанини алат. Эгер ал промис болсо, анын чечилишин же четке кагылышын күтөт. -
Иштөөнү кайра жандандыруу (
next()): Асинхрон операция (промис чечилгенден кийин) аяктагандан кийин, асинхрон жыйынтык (промис мааниси) кайра генераторгоnext()аркылуу өткөрүлөт. Генератор токтогон жерден ишин улантат. -
Натыйжаны өткөрүү:
next()аркылуу берилген маанисиyieldичиндеги маанинин натыйжасы болот. Ошентип, генератор асинхрон операциянын натыйжасын "алып", анын менен иштей берет, код синхрондуудай көрүнөт.
Бул үлгү асинхрондук операциялар үчүн синхрондуу аткаруу сыялуулугун түзүп, кодду окуу жана башкаруу жагынан жеңилдетет, классикалык callbackтер же татаал шынжырлар .then() колдонуу менен салыштырып.
Мисал катары co типтеги каптоо колдонулушу мүмкүн (азыр кеңири тараган async/await бар, ал негизинен синтаксистик шекер):
// Асинхрондуулук үчүн генератор колдонуу мисалы
function* myAsyncGenerator() {
try {
const result1 = yield Promise.resolve(1); // Токтотуу, промис кайтаруу
console.log('Биринчи натыйжа алынды:', result1); // Натыйжаны өткөрүү менен улантуу
const result2 = yield new Promise(resolve => setTimeout(() => resolve(2), 500)); // Башка бир асинхрон иш
console.log('Экинчи натыйжа алынды:', result2);
return 'Даяр'; // Генераторду аяктоо
} catch (error) {
console.error('Ката кетти:', error);
}
}
// Генератор үчүн жөнөкөй "жүгүргүч" (жөнөкөйлөтүлгөн)
function run(generatorFunc) {
const generator = generatorFunc();
function handleNext(newValue) {
const result = generator.next(newValue);
if (!result.done) {
if (result.value instanceof Promise) {
result.value.then(handleNext).catch(handleError);
} else {
handleNext(result.value);
}
} else {
console.log('Генератор бүттү:', result.value);
}
}
function handleError(error) {
generator.throw(error);
}
handleNext(); // Генераторду иштетүү
}
// Биз биздин асинхрон генераторду иштетебиз
run(myAsyncGenerator);
Бул мисалда, yield Promise.resolve(1) генераторду токтотот. "Жүгүргүч" (же co) промис чечилгенге чейин күтөт жана андан кийин генераторду кайра жандандырып, маанини next(1) аркылуу өткөрөт. Бул маані 1 yield Promise.resolve(1) ичиндеги натыйжа болуп, аны кийинки сапта (console.log) иштетүүгө мүмкүндүк берет. Бул механизм асинхрондук операциялар үчүн синхрондуу аткаруу агымын имитациялоого мүмкүндүк берет.