ES6-Generator使用与改写

用Generator封装Symbol中的iterator方法:

 

注意:Generator的function后必须写*  

 

config:分别有3个txt文件,两个文件写路径,一个文件写要输出的内容

前置写法,node引入fs:

let fs = require('fs');

function read(path){
    return new Promise((res, rej) => {
        fs.readFile(path, 'utf-8', (err,data) => {
            if(data){
                res(data);
            }else{
                rej(err);
            }
        })
    })
}

 

 

  

当前的迭代方法:
    let obj = {
            0: 'a',
            1: 'b',
            2: 'c',
            length:4,
            [Symbol.iterator]: function (){
                let index = 0;
                let next = () => {
                    return {
                        value: this[index],
                        done: this.length == ++index
                    }
                }

                return {
                    next
                }
            }
        }

        console.log([...obj]);//(3) ["a", "b", "c"]

        for(let p of obj){
            console.log(p);//a b c
        }

改写后的方法:
        let obj = {
            0: 'a',
            1: 'b',
            2: 'c',
            length:3,
            [Symbol.iterator]: function* (){
                let index = 0;
                while(index != this.length){
                    yield this[index++]
                }
            }
        }

        console.log([...obj]);//(2) ["a", "b"]

        for(let p of obj){
            console.log(p);//a b
        }


    

 

 

用promise解决回调地狱问题与Generator方法对比

let fs = require('fs');

function read(path){
    return new Promise((res, rej) => {
        fs.readFile(path, 'utf-8', (err,data) => {
            if(data){
                res(data);
            }else{
                rej(err);
            }
        })
    })
}


read('./number.txt').then((value) => {
    
    return read(value);
}).then((value) => {
    return read(value);
}).then((value) => {
    console.log(value);
})

以上缺点调用太多次then方法

 

 

那么我们用Generator方法解决一下回调地狱

function * readA() {

    let val1 = yield read('./number.txt');
    let val2 = yield read(val1);
    let val3 = yield read(val2);

    return val3;
}
//返回Generator对象
let oG = readA();

let {value, done} = oG.next();

value.then((val) => {
    let {value, done} = oG.next(val);
    value.then((val) => {
        let {value, done} = oG.next(val);
        value.then((val) => {
            console.log(val)
        })
    })
})

缺点:与回调地狱无区别

 

Generator优化:

注意:必须引入fs模块才能运行

function * readA() {

    let val1 = yield read('./number.txt');
    let val2 = yield read(val1);
    let val3 = yield read(val2);

    return val3;
}


function Co(oIt){
    return new Promise((res, rej) => {
        let next = (data) => {
            let {value, done} = oIt.next(data);
            if(done != true){
                value.then((val) => {
                    next(val);
                })
            }else{
                res(value);
            }

        }
        next();
    })
}


Co(readA()).then((val) => {
    console.log(val)
})

 

node有co模块,在npm下载使用,效果一样

posted @ 2019-05-06 18:50  set_Promise  阅读(236)  评论(0编辑  收藏  举报