什么是JavaScript generator

什么是JavaScript generator

JavaScript是单线程的,程序写到哪里执行到哪里。如果一个function里循环,不释放线程的计算时间,就会造成浏览器用户界面的冻结。下面一段代码展示,在foo循环执行时,在没有执行完循环之前,timer不会触发,虽然timer只设置了1毫秒。

setTimeout(function(){
    console.log("Hello World");
},1);

function foo() {
    // NOTE: don't ever do crazy long-running loops like this
    for (var i=0; i<=1E10; i++) {
        console.log(i);
    }
}

foo();
// 0..1E10
// "Hello World"

ES6引进了yield,在写function generator的时候,在函数执行是,可以通过yield来放弃当前执行时间,直到当函数再次被调用的时候,从上次yield执行的位置继续执行函数体。
所以后面这段代码很有意思,它不是像常规函数执行时那样一行行的执行下去,而是要外部某个地方,不停的执行这个函数,它才会每次从上次间断了的yield的位置执行。
你可以把这段代码copy到浏览器的console里,然后不断地调用foo()来看效果。

function *foo() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
}
var it = foo();

结果应该大概是这样的:

console.log( it.next() ); // { value:2, done:false }
console.log( it.next() ); // { value:3, done:false }
console.log( it.next() ); // { value:4, done:false }
console.log( it.next() ); // { value:5, done:false }

利用这个特性,ES6就很容易实现iterator模式。例如for...of会迭代对象的iterator来显示内容:

function *foo() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
    return 6;
}

for (var v of foo()) {
    console.log( v );
}
// 1 2 3 4 5

console.log( v ); // still `5`, not `6` :(

上述例子都来自这篇文章,感谢他把ES6 generator讲的这么清晰。

参考:https://davidwalsh.name/es6-generators

leon

每天进步一点点