Condivisione della tecnologia

Applicazione asincrona della funzione Generatore ES6 (8)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

L'applicazione asincrona delle funzioni del generatore ES6 viene implementata principalmente utilizzandolo insieme a Promise. Questo modello è chiamato modello "thunk" e consente di scrivere codice asincrono che sembra essere sincrono.

caratteristica:

  1. Sospendere l'esecuzione: Quando la funzione Generator incontra un'espressione yield, metterà in pausa l'esecuzione e attenderà che la Promise venga risolta.
  2. Riprendere l'esecuzione: Quando la Promessa viene completata (risolta o rifiutata), la funzione Generator riprende l'esecuzione e restituisce il risultato dell'espressione yield.
  3. Gestione degli errori: gli errori nelle operazioni asincrone possono essere acquisiti ed elaborati.
  4. chiamata a catena: è possibile creare una catena di operazioni asincrone, ciascuna operazione inizia dopo il completamento dell'operazione precedente.

1. Funzione generatore asincrono di base

function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time));
}

function* asyncGenerator() {
    console.log("Start");
    yield delay(1000); // 等待1秒
    console.log("After 1 second");
    yield delay(1000); // 再等待1秒
    console.log("After another second");
    return "Done";
}

let gen = asyncGenerator();

function runGenerator(g) {
    let result = g.next();
    result.value.then(() => {
        if (!result.done) {
            runGenerator(g);
        }
    });
}

runGenerator(gen);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2. Utilizzare for...of e async...attendere lo zucchero della sintassi

// 假设我们有以下 async generator
async function* asyncGen() {
    yield await Promise.resolve(1);
    yield await Promise.resolve(2);
    yield await Promise.resolve(3);
}

// 我们可以使用 for...of 循环和 async...await 语法糖来简化调用
(async () => {
    for await (let value of asyncGen()) {
        console.log(value); // 依次输出 1, 2, 3
    }
})();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3. Gestione degli errori nelle operazioni asincrone

function* asyncGenWithError() {
    try {
        yield Promise.reject("Error occurred!");
    } catch (e) {
        console.log(e); // 输出:Error occurred!
    }
}

let genWithError = asyncGenWithError();

genWithError.next().value.catch(err => console.log(err));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4. Utilizzare yield* per delegare ad altre funzioni asincrone del generatore

function* innerAsyncGen() {
    yield Promise.resolve("A");
    yield Promise.resolve("B");
}

function* outerAsyncGen() {
    yield "Start";
    yield* innerAsyncGen(); // 委托给另一个异步 Generator 函数
    yield "End";
}

let outerGen = outerAsyncGen();

function runOuterGenerator(g) {
    let result = g.next();
    result.value.then(val => {
        if (!result.done) {
            runOuterGenerator(g);
        }
    });
}

runOuterGenerator(outerGen);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23