看 ssh_晨曦时梦见兮 : <手写async await的最简实现> 自己记录

49 阅读3分钟
//不断调用next,根据值判断是 最后一步 / 下一个next
//最初版本
function asyncToGenerator(generatorFunc) {
    const gen = generatorFunc(arguments);
    //拿到gen后,根据它的返回值决定继续执行next还是直接结束resolve
    //自动执行next的方法,一旦调用,拿到值并进行判断
    function nextFunc(val) {
        const { value, done } = gen.next(val);
        if (done) {
            return value;
        } else {
            nextFunc(value);
        }
    }
    nextFunc();
}


//处理异步,异步是promise,所以需要处理promise,需要then
//  针对value这个promise进行处理
// function asyncToGenerator(generatorFunc) {
//   const gen = generatorFunc(arguments);
//   //拿到gen后,根据它的返回值决定继续执行next还是直接结束resolve
//   //自动执行next的方法,一旦调用,拿到值并进行判断
function nextFunc(val) {
    const { value, done } = gen.next(val);
    if (done) {
        // return value; //最后一步暂时不管
        value.then(
            (res) => console.log(res),
            (err) => console.log(err)
        );
    } else {
        value.then(
            (res) => nextFunc(res),
            (err) => nextFunc(err)
        );
            // nextFunc(value);
            /\*\*
            \* 针对value进行处理,这个地方的value基本上只会是promise,如何
            \*  处理promise,让then的时候再将最后的值传下去
            \* */
        }
    }
    nextFunc();
}


/*\*

*   1.防止yeild后面的数据不是promise而是普通数据,所以用promise
*   套一层防止这个问题,promise可以接受promise,也可以接受普通数据,
*   需要返回promise,就可以考虑这些。
*   2.async,promise都会返回promise
    */
    function asyncToGenerator(generatorFunc) {
        const gen = generatorFunc(arguments);
        //拿到gen后,根据它的返回值决定继续执行next还是直接结束resolve
        //自动执行next的方法,一旦调用,拿到值并进行判断
        function nextFunc(val) {
            const { value, done } = gen.next(val);
            if (done) {
                // return value; //最后一步暂时不管
                Promise.resolve(value).then(
                    (res) => console.log(res),
                    (err) => console.log(err)
                );
            } else {
                Promise.resolve(value).then(
                    (res) => nextFunc(res),
                    (err) => nextFunc(err)
                );
                // nextFunc(value);
                /*\*
                \* 针对value进行处理,这个地方的value基本上只会是promise,如何
                \*  处理promise,让then的时候再将最后的值传下去
                \* */
            }
        }
        nextFunc();
    }
    
    
    /*\*
*   1.因为模拟的是async函数,这个函数返回一个promise,promise的值
*   是return的数据,所以外层包裹一层promise
*   2.只有最后一步需要抛出,所以只有return需要return
    */
    function asyncToGenerator(generatorFunc) {
        const gen = generatorFunc(arguments);
        //拿到gen后,根据它的返回值决定继续执行next还是直接结束resolve
        //自动执行next的方法,一旦调用,拿到值并进行判断
        return new Promise((resolve, reject) => {
            function nextFunc(val) {
                const { value, done } = gen.next(val);
                if (done) {
                    // return value; //最后一步暂时不管
                    Promise.resolve(value).then(
                        (res) => resolve(res),
                        (err) => console.log(err)
                    );
                } else {
                    Promise.resolve(value).then(
                        (res) => nextFunc(res),
                        (err) => nextFunc(err)
                    );
                        // nextFunc(value);
                        /*\*
                        \* 针对value进行处理,这个地方的value基本上只会是promise,如何
                        \*  处理promise,让then的时候再将最后的值传下去
                        \* */
                }
            }
            nextFunc();
        });
    }
    
    
    //错误捕获
    function asyncToGenerator(generatorFunc) {
        const gen = generatorFunc(arguments);
        //拿到gen后,根据它的返回值决定继续执行next还是直接结束resolve
        //自动执行next的方法,一旦调用,拿到值并进行判断
        return new Promise((resolve, reject) => {
            function nextFunc(genType, val) {
                let genResult;
                try {
                    genResult = gen[genType](val);
                } catch (err) {
                    reject(err);
                }
                const { value, done } = genResult;
                if (done) {
                    // return value; //最后一步暂时不管
                    Promise.resolve(value).then(
                        (res) => resolve(res),
                        (err) => reject(err)
                    );
                } else {
                    Promise.resolve(value).then(
                        (res) => nextFunc("next", res),
                        (err) => nextFunc("throw", err) //这个是为了在下一次next抛出错误
                    );
                        // nextFunc(value);
                        /*\*
                        \* 针对value进行处理,这个地方的value基本上只会是promise,如何
                        \*  处理promise,让then的时候再将最后的值传下去
                        \* \*/
                }
            }
            nextFunc("next");
        });
    }
    
    //不是promise内部可以接受一个promise,是promise的resolve或者reject
    // 内部可以接受一个promise,如果是promise可以自动解包,不是也没问题
    // 并且接受的promise最好是状态相同,不然不会解包

const getData = () =>
new Promise((resolve) => setTimeout(() => resolve("data"), 1000));

var test = asyncToGenerator(function\* testG() {
//自执行并拿到返回值
// await被编译成了yield
const data = yield getData(); //先走一步next,再根据这个next的值来决定是否走下一个next
console.log("data: ", data);
const data2 = yield getData();
console.log("data2: ", data2);
return getData();
}).then((res) => console.log(res));