实现co模块中的co方法

co模块:是为了简化状态函数的启动过程 
 
ES6提供了co模块,又提供了co方法,用于简化状态函数的启动
 
当调用了co方法之后,可以通过then方法监听状态的改变
 
在之前,我们定义三个异步函数,让其一个接一个执行,且第一个任务处理结果传递给第二个任务,第二个任务处理的结果传递给第三个任务
代码如下:
<script>
    // 定义三个异步操作
    let task1 = () => {
        return new Promise((resolve, reject) => {
            // 1秒之后打印字符串
            setTimeout(() => {
                console.log('task1 执行完毕')
                resolve('task1');
            }, 1000)
        })
    }
    let task2 = () => {
        return new Promise((resolve, reject) => {
            // 2秒之后打印字符串
            setTimeout(() => {
                console.log('task2 执行完毕')
                // resolve('task2');
                reject('task2')
            }, 2000)
        })
    }
    let task3 = () => {
        return new Promise((resolve, reject) => {
            // 3秒之后打印字符串
            setTimeout(() => {
                console.log('task3 执行完毕')
                resolve('task3');
            }, 3000)
        })
    }
    // 让三个异步操作,一个接一个的执行,
    // 第一个任务处理结果传递给第二个任务,
    // 第二个任务处理的结果传递给第三个任务
    function *main(result) {
        // 执行第一个任务
        result = yield task1(result);
        console.log(11, result);
        // 执行第二个任务
        result = yield task2(result);
        console.log(22, result);
        // 执行第三个任务
        result = yield task3(result);
        console.log(33, result);
        // 返回最终的结果
        return result;
    }
    // 启动程序
    let m = main('red'); 
    // 执行第一个任务
    // 第一次传递不需要接收参数
    m.next().value.then(() => {
        // 执行第二个任务
        m.next('green').value.then(() => {
            // 执行第三个任务
            m.next('yellow').value.then((res) => {
                console.log('最终的结果', res);
            }, () => {
                m.next('blue').value.then((res) => {
                    console.log('最终的结果', res);
                })
            })
        })
    })

可以看出,通过next()方法遍历通过then()方法监听,需要一层一层嵌套,于是ES6提供了co模块,又提供了co方法,用于简化状态函数的启动

代码如下

// 通过co方法启动main
co(main)
    // 直接监听最终的结果
    .then(res => console.log('最终结果是:', res), 
            err => console.log('执行失败了', err))

实现co方法:

function co(gen) {
        // 返回一个promise方法
        return new Promise((resolve, reject) => {
            // 执行generator函数
            let g = gen();
            // 定义递归函数
            function myNext(res) {
                // 定义运行结果
                let result;
                // 为了防止代码出现错误 我们可以将语句放入try catch中
                try {
                    result = g.next(res);
                } catch(e) {
                    // 出现错误程序中断
                    return reject(e);
                }
                // 一旦遍历完成,终止执行
                if(result.done) {
                    return resolve(result.value);
                }
                // 进入下一项
                result.value.then(() => {
                    myNext(result.value);
                })
                .catch(err => console.log(err))
            }
            // 执行next
            myNext();
        })
    }
原文地址:https://www.cnblogs.com/yess/p/13139828.html