Во-первых, генераторы - это не про асинхронность (хотя можно и для нее использовать, но не нужно), генераторы - это про прерываемые вычисления и управляемые итераторы.
Например с помощью генераторов хорошо решаются задачи на бесконечные последовательности:
function* fibo() {
let prev = 1;
let prePrev = 1;
yield prePrev;
yield prev;
while(true) {
let cur = prePrev + prev;
yield cur;
prePrev = prev;
prev = cur;
}
}
for(let val of fibo()) {
alert(val);
if(val > 100) { break; }
}
Во-вторых, для асинхроности есть промисы и сахар над ними в виде async/await
async function то же прерывается когда видит await, подобно генератору (именно по этому на генераторах и эмитируют async/await при транспайлинге в старый стандарт)
но в отличии от генератора, который ждет от внешнего кода команды .next() для продолжения выполнения после yeild, async function ждет резолва или реджекта промиса переданного в await