Niyə adi generatorlar asinxron kod yazmağa imkan verir?
sobes.tech Süni İntellekt
AI-dan cavab
JavaScript-də adi generatorlar, icraatı dayandırmaq və yenidən başlatmaq qabiliyyətinə malik olduqları üçün, həmçinin yield və next() vasitəsilə dəyərləri hər iki istiqamətdə ötürə bildikləri üçün, asinxron kod yazmağa imkan verir.
Budur, bu necə işləyir asinxronluq kontekstində:
-
İcraatı dayandırmaq (
yield):yieldəmrinə çatdıqda, generator dayandırılır və bir dəyər qaytarır. Asinxron kodda, bu dəyər bir vəd (promise) və ya başqa bir "hərəkət" ola bilər ki, asinxron şəkildə yerinə yetirilməlidir. -
Asinxron nəticəni gözləmək: Xarici kod (məsələn, bir "runner" və ya generator üçün qaplama)
yieldvasitəsilə ötürülən dəyəri alır. Əgər bu, promise isə, onun həll olunmasını və ya rədd edilməsini gözləyir. -
İcraatı davam etdirmək (
next()): Asinxron əməliyyat (promise-in həll olunması) tamamlandıqdan sonra, asinxron nəticə (promise-in dəyəri) yenidən generatoranext()metodu ilə ötürülür. Generator dayandırıldığı yerdən davam edir. -
Nəticənin ötürülməsi:
next()-ə ötürülən dəyər, generator daxilindəkiyieldifadəsinin nəticəsi olur. Bu yolla, generator, asinxron əməliyyatın nəticəsini "ala" bilər və onunla işləməyə davam edə bilər, sanki kod sinxron imiş kimi.
Bu nümunə, asinxron əməliyyatlar üçün sinxron icra axını illüziyasını yaradır, kodu daha oxunaqlı və idarə edilə bilən edir, ənənəvi callback-lər və ya mürəkkəb .then() zəncirləri ilə müqayisədə.
Bunun nümunəsi, co kimi qaplamalar vasitəsilə olur (hazırda async/await daha çox istifadə olunur, bunlar əsasən generatorlar və promise-lər üzərində sintaktik şəkərdir):
// Asinxronluq üçün generator nümunəsi
function* myAsyncGenerator() {
try {
const result1 = yield Promise.resolve(1); // Dayandırır, promise qaytarır
console.log('Birinci nəticə:', result1); // Qiymətlə davam edir
const result2 = yield new Promise(resolve => setTimeout(() => resolve(2), 500)); // Başqa bir asinxron əməliyyat
console.log('İkinci nəticə:', result2);
return 'Hazır'; // Generatori bitir
} catch (error) {
console.error('Xəta baş verdi:', error);
}
}
// Generator üçün sadə "runner" (sadələşdirilmiş)
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('Generator tamamlandı:', result.value);
}
}
function handleError(error) {
generator.throw(error);
}
handleNext(); // Generator-i işə sal
}
// Asinxron generatorimizi işə salırıq
run(myAsyncGenerator);
Bu nümunədə, yield Promise.resolve(1) generatori dayandırır. "Runner" (və ya co) promise-in həll olunmasını gözləyir və sonra generatoru next(1) ilə davam etdirir. Bu dəyər 1, generator daxilində yield Promise.resolve(1)-in nəticəsi olur və onu növbəti sətirdə (console.log) işləməyə imkan verir. Bu mexanizm, asinxron əməliyyatlar üçün sinxron icra axını imitasiyasını təmin edir.