0

0

0

修罗

站点介绍

只有了解事实才能获得真正的自由

generator实现async、await

修罗 2021-12-20 1607 0条评论 JS

首页 / 正文

定义生成器

generator生成器函数的*模拟async,yield模拟await

function* gener() {
    let result = yield Promise.resolve("async await");
    console.log("result ", result);
}

如果我们将yield当成我们常用的await,那么result返回的应该是promise的结果;

执行生成器

let gen = gener();
let firstExec = gen.next();

console.log(firstExec.value, firstExec.done); // Promise false

通过调用next方法拿到yield后面的结果{ value:promise, done:false },生成器gener方法内部打印result需要再次调用next方法,将第一次的value传给next方法,这个参数会作为yield的返回值。

let secExec = gen.next(firstExec.value);
// done为true表示调用结束
console.log(secExec.value, secExec.done); // undefined true 

result打印promise。也可以next直接传promise的结果,await用法就是这样。

函数封装调用

通过函数封装调用代码,编写生成器的执行器:

function execGener(gener) {
    let gen = gener();
    let firstExec = gen.next();
    firstExec.value.then((res) => {
        gen.next(res);
    });
}

// 执行生成器
execGener(gener); // result  async await

上面只能处理一次yield ,下面情况无法处理,因为上面只调了两次next。

function* gener() {
    let result = yield Promise.resolve("async await");
    let result1 = yield Promise.resolve("async await1");
    console.log("result ", result);
    console.log("result ", result1);
}

加强方法

递归调用next,直到yield执行完毕,next的done返回true表示生成器执行完毕。

function execGener(gener) {
    let gen = gener();
    function next(data) {
        let result = gen.next(data);
        if (result.done) return; // 递归出口,出口之前还会调一次next,是为了把数据给上一个yeild结果,因为第二次next之后才能给yield结果赋值。
        result.value.then((res) => {
            next(res);
        });
    }
    next();
}

// 执行生成器
execGener(gener);

执行流程解析:

  • 第一次调gen.next,返回值value拿到第一个promise;
  • 第二次调gen.next,传参第一个promise的结果,于是result被赋值为第一个promise,随后执行第二个yield,返回值value拿到第二个promise;
  • 第三次调gen.next,传参第二个promise的结果给result1赋值,执行结束。

1639943278633.png

评论(0)


最新评论

  • https://www.studyglobus.com/author/carroll34a5552/

    Ценники на вывоз мусора сейчас космос, любые лайфхаки по экономии в тему.

  • Richardgrold

    1xbet onlayn kazino platforması ilə vaxtınızı daha səmərəli və maraqlı keçirin. Saytın canlı kazino bölməsi istifadəçilərə fərqli bir dünya təklif edir. Burada canlı dilerli kazino oyunlarının hər bir növünü sınaqdan keçirə bilərsiniz. Krupyelərin peşəkarlığı oyunun dinamikasını və marağını artırır. Müntəzəm olaraq yenilənən oyun siyahısı cansıxıcılığa yol vermir. Hesabınızı artırmaq üçün onlarla fərqli və etibarlı üsul mövcuddur. Qazanılan pullar cəmi bir neçə dəqiqə ərzində şəxsi hesabınıza köçürülür. Aktiv fəaliyyətinizə görə fərdi bonuslar və hədiyyələr qazana bilərsiniz. Dəstək xidməti həm çat, həm də e-poçt vasitəsilə kömək göstərir. 1xbet ailəsinə qoşulun və böyük uduşlar üçün ilk addımı atın. onlayn kazino

  • 砂岩白丘

    我一直梦想, 看到你们相册那样的地方。真棒。

  • 城市地標

    我喜欢, 这里分享真实经验。你的项目 就是 属于这里的。请继续。

  • 宗教地標

    我热爱这样的想法, 去那么多国家。真的很鼓舞。

  • 觀景高地

    能感受到热爱。继续保持 感受。

  • 最佳季節

    我关注这样的资源, 写得很实在。你的网站 就是 属于这里的。加油。

  • 1

    1

  • 1

    1

  • -1' OR 2+158-158-1=0+0+0+1 or 'TKCTZnRa'='

    1

日历

2026年07月

   1234
567891011
12131415161718
19202122232425
262728293031 

文章目录

推荐关键字: Linux webpack js 算法 MongoDB laravel JAVA jquery javase redis