zoukankan      html  css  js  c++  java
  • async await 原理——generator 自执行

    generator 函数自执行

    redux-saga 中使用 generator 函数来进行流程控制。通常的 generator 函数在 yield 的地方中止后,需要使用 next 来继续执行,但是 saga 使用中我们并没有调用 next,说明 saga 已经在内部进行了处理,那么它是怎么处理的呢?

    首先我们来看一个 generator 函数是怎样的:

    function* gen() {
        yield 'a';
        yield 'b';
        return 'c';
    }
    const g = gen();
    g.next();  // { value: a, done: false }
    g.next();  // { value: b, done: false }
    g.next();  // { value: c, done: true }
    

    以上是一个基本的 generator 函数,我们需要使用 next 来执行。
    那么如何让它自执行呢?

    function next(g) {
        const { value, done } = g.next();
        if (!done) next(g);  // done 为 false,则递归调用 next
    }
    const g = gen();
    next(g);
    

    这样我们就能自执行上面那个简单的 generator 函数了。

    但是,通常情况下,generator 函数中 yield 后面会是一个异步操作,通常是一个 promise 对象来进行,那么又是个什么情况呢?

    // 首先声明一个异步调用方法,该方法返回一个 promise 对象
    const asyncAdd = (num) => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                num++;
                console.log('异步请求完成');
                resolve(num);
            }, 1000);
        });
    };
    
    function* add(num) {
        const res = yield asyncAdd(num);
        yield asyncAdd(res);
    }
    

    上面这个 generator 手动调用该怎么做呢?

    const g = add(10);
    // 调用 next 后获取到的 value,这时就是一个 promise 对象:{value: promise, done: false}
    // 我们就需要调用 promise 的 then 方法来继续执行
    g.next().value.then(num => g.next(num));
    

    通过观察,我们就可以实现一个异步调用的自执行 generator 函数:

    // 增加了一个 data 参数,作为 generator 内部 yield 的返回值
    // 首次调用 next 的时候,值是在调用 generator 函数就传了,而不是在 .next 时传,所以 data 为 undefined 即可
    function next(g, data) {
        // 通过调用 next 传入数据作为 generator 内部 yield 的返回值
        const { value, done } = g.next(data);
        // 按理来说需要判断 value 类型
        if (!done) value.then(res => next(g, res));
    }
    const g = add(10);  // 首次传参
    next(g);
    

    这样,就实现了带 promise 的 generator 自执行函数。

  • 相关阅读:
    java.security.InvalidKeyException: Illegal key size aes解密失败
    Java获取URL链接的文件类型
    解决eclipse中web项目出现Project facet Java version 1.8 is not supported.的问题
    探讨一下Java单例设计模式
    HTML5文件上传qq、百度、taobao等比较(改进支持三种状态提示)
    jQuery Ajax 上传文件改进
    Java POI 3.17写入、导入EXCEL性能测试
    jQuery Ajax 上传文件夹及文件
    Java 打包下载服务器上选中的文件或目录(带进度条提示)
    pio 背景色
  • 原文地址:https://www.cnblogs.com/3body/p/15476701.html
Copyright © 2011-2022 走看看