Generator初识

2020-04-04 00:30:01 908 思小齐 思小齐

一、简介

Generator函数是ES6引入的新型函数,用于异步编程,跟Promise对象联合使用的话会极大降低异步编程的编写难度和阅读难度。

与普通函数的区别:

  1. function关键字与函数名之间有一个星号;
  2. 函数体内部使用yield语句,定义不同的内部状态(yield在英语里的意思就是“产出”)。

二、简单示例

1、yield和return

function* Foo() {
    yield 'hello';
    yield 'world';
    return '!';
}
var foo = Foo();

console.log(foo.next());
console.log(foo.next());
console.log(foo.next());

clipboard.png

注意:generator函数不能直接使用,是通过next()方法获取yield/return的返回结果,而return可以提前终止函数。foo.return('!')方法也可终止函数。

2、yield*

字符串方式

function* Foo() {
    yield* 'hello';
}
var foo = Foo();

console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());

打印结果:

clipboard.png

数组方式

function* Foo() {
    yield* ['a', 'b', 'c'];
}
var foo = Foo();

console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());

打印结果:

clipboard.png

3、与for of配合使用

yield和return

function* Foo() {
    yield 1;
    yield 2;
    return 3;
}
var foo = Foo();

for(var v of foo) {
    console.log(v);
}

打印结果:

clipboard.png

从上可以看出for of不执行return值

yield*

function* Foo() {
    yield* 'hello';
}
var foo = Foo();

for(var v of foo) {
    console.log(v);
}

打印结果:

clipboard.png

4、throw方法

function* Foo() {
    try {
        yield;
    } catch(e) {
        console.log('内部捕获', e);
    }
}

var foo = Foo();
foo.next();

try {
    foo.throw('a');
    foo.throw('b');
} catch (e) {
    console.log('外部捕获', e);
} 

clipboard.png

三、配合Promise使用

function promiseFn() {
    new Promise(function(resolve, reject) {
        setTimeout(function() {
            foo.next('G');
        }, 1000);
    });
}

function* Foo() {
    var a = yield promiseFn();
    var b = yield promiseFn();
    console.log(a, 111);
    console.log(b, 222);
}

var foo = Foo(); // foo是全局变量,挂在window上,存在变量提升,在执行到promise异步的时候,可以直接使用
foo.next();

clipboard.png

四、配合ajax使用

demo.php

<?php
header('content-type: application/json');
$a = ['name'=>'tom','age'=>rand()];
echo json_encode($a);

demo.html

function ajax() {
    $.ajax({
        type: 'get',
        url: 'demo.php',
        success: function(res) {
            foo.next(res);
        },
        error: function(error) {
            foo.next(error);
        }
    });
}

function* Foo() {
    var a = yield ajax();
    var b = yield ajax();
    console.log(a, 111);
    console.log(b, 222);
}

var foo = Foo();
foo.next();

打印结果:

clipboard.png