Generator理解

307 阅读2分钟

虽然自己也学过,写项目也一直在用Generator,react-sage,dva,umi,写react用到redux,就会用到,但自己总是一知半解的,今天用空自己总结一下自己学的。

看例子

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

这样看起来很容易理解 console.log()后发现返回的是一个对象有一个value和done,然后next()向后接着执行就好,但是像下面这样

function *ab(){
    let c = yield new Promise(
        (res,rej)=>{
            setTimeout(()=>{res('hello world')},2000)
        }
    );
    console.log('c',c);
    let d =  yield new Promise(
        (res,rej)=>{
            setTimeout(()=>{res('hello2 world2')},2000)
        }
    );
    console.log('d',d);
}
let it= ab()
console.log(it.next());
console.log(it.next());
console.log(it.next());

执行后是这个样子

{ value: Promise { <pending> }, done: false }
c undefined
{ value: Promise { <pending> }, done: false }
d undefined
{ value: undefined, done: true }

这样执行

console.log(it.next(1));
console.log(it.next(2));
console.log(it.next(3));

是这个样子

{ value: Promise { <pending> }, done: false }
c 2
{ value: Promise { <pending> }, done: false }
d 3
{ value: undefined, done: true }

个人比较迷糊,安装我理解async的样子应该是c等于Promise执行后的结果 如下

async function ab(){
    let c= await new Promise(
        (res,rej)=>{
            setTimeout(()=>{res('hello world')},2000)
        }
    )
    console.log('c',c);
    let d =  await new Promise(
        (res,rej)=>{
            setTimeout(()=>{res('hello2 world2')},2000)
        }
    );
    console.log('d',d);
}
ab()

结果

c hello world
d hello2 world2

后来自己理解Generator“函数”和“执行”是分开的,怎么“执行”也决定了“函数”的结果 看下面这样执行Generator

it.next(1).value.then(res=>{
    console.log('res',res);
    it.next(res).value.then(res2=>{
        console.log('res2',res2);
        it.next(res2)
    })
})

这样执行就是我想要的结果

res hello world
c hello world
res2 hello2 world2
d hello2 world2

next()传入的值会成为yield后的返回值 像这样

function* helloWorldGenerator() {
    let a = yield 'hello';
    console.log(a);
    let b = yield 'world';
    console.log(b);
    return 'ending';
}
var hw = helloWorldGenerator();
console.log(hw.next(1));
console.log(hw.next(2));
console.log(hw.next(3));

这结果

{ value: 'hello', done: false }
2
{ value: 'world', done: false }
3
{ value: 'ending', done: true }

理解总结:next()执行的时间和传入的参数决定了Generator函数的执行结果,要把函数和执行器分开理解

async函数就是Generator的语法糖 相当于加了自执行 执行器,原理如下

function spawn(genf){
    return new Promise(function(resolve,reject){
        const gen=genf()
        function step(nextF){
            let next
            try{
                next=nextF()
            } catch(e){
                return reject(e)
            }
            if(next.done){
                return resolve(next.value)
            }
            Promise.resolve(next.value).then(function(v){
                step(function(){return gen.next(v)})
            },function(e){
                step(function(){return gen.trow(e)})
            })
        }
        step(function(){return gen.next(6)})
    })
}
spawn(ab).then(res=>{
    console.log('res',res);
});

学过的知识过一段就忘了,自己总结一下印象会跟深刻一些,自己下次再看也更容易理解。最后还是多看文档。