Чаро генераторҳои оддӣ имкон медиҳанд, ки коди асинхронӣ нависанд?
sobes.tech AI
Ҷавоб аз AI
Генераторҳои одии JavaScript имкон медиҳанд, ки коди асинхрониро навишт, бо сабаби қобилияти онҳо дар истодан ва такмил додани иҷро, инчунин интиқол додани арзишҳо дар ҳар ду самт (yield ва next()).
Ин аст, ки чӣ гуна ин дар контексти асинхронӣ кор мекунад:
-
Истодан дар иҷро (
yield): Вақте ки ба операториyieldмерасад, генератор истода мешавад ва арзишро бармегардонад. Дар коди асинхронӣ, ин арзиш метавонад як promise ё дигар "амал" бошад, ки бояд асинхронӣ иҷро шавад. -
Интизор шудан барои натиҷаи асинхронӣ: Коди беруна (масалан, "роннер" ё фароранда барои генератор) арзишеро, ки тавассути
yieldдода шудааст, мегирад. Агар ин promise бошад, интизор мешавад, ки он ҳал ё рад шавад. -
Такмил додани иҷро (
next()): Пас аз анҷоми амалиёти асинхронӣ (ҳал шудани promise), натиҷаи асинхронӣ (арзиши promise) ба генератор тавассути методиnext()баргардонида мешавад. Генератор иҷрои худро аз ҷое, ки боздошта буд, идома медиҳад. -
Пас додани натиҷа: Арзиши, ки ба
next()дода мешавад, натиҷаи изразиyieldдар дохили генератор мешавад. Ин имкон медиҳад, ки генератор "назар" ба натиҷаи амалиёти асинхронӣ дошта бошад ва бо он идома диҳад, гӯё ки код синхронӣ бошад.
Ин модел иллюзияи иҷрои синхронӣ барои амалиётҳои асинхронро эҷод мекунад, ки коди онро хондан ва идора кардан осонтар мекунад дар муқоиса бо истифодаи анъанавии callback ё занҷирҳои мураккаб .then().
Масалан, ин гуна истифодаи co (ҳарчанд ҳоло бештар async/await маъмул аст, ки асосан сахттар кардани синтаксис дар болои генераторҳо ва promise-ҳо мебошанд):
// Масалан истифодаи генератор барои асинхронӣ
function* myAsyncGenerator() {
try {
const result1 = yield Promise.resolve(1); // Истодан, баргардонидани promise
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) интизор мешавад, ки promise ҳал шавад, ва пас генераторро бо next(1) такмил медиҳад. Ин арзиш 1 мешавад натиҷаи yield Promise.resolve(1) дар дохили генератор, ки имкон медиҳад онро дар сатрҳои оянда (console.log) коркард кунад. Ин механизм имкон медиҳад, ки имитацияи ҷараёни синхронии иҷро барои амалиётҳои асинхронӣ ба вуҷуд ояд.