JavaScript学习笔记十六:generator

JavaScript教程传送门

generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。

generator和函数不同的是,generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次:

function* foo(x) {
    yield x + 1;
    yield x + 2;
    return x + 3;
}

编写一个产生斐波那契数列的函数,可以这么写:

function* fib(max) {
    var
        t,
        a = 0,
        b = 1,
        n = 1;
    while (n < max) {
        yield a;
        t = a + b;
        a = b;
        b = t;
        n ++;
    }
    return a;
}

调用generator对象有两个方法,一是不断地调用generator对象的next()方法:

var f = fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window},fib(5)仅仅是创建了一个generator对象,还没有去执行它
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: true}

第二个方法是直接用for ... of循环迭代generator对象,这种方式不需要我们自己判断done

for (var x of fib(5)) {
    console.log(x); // 依次输出0, 1, 1, 2, 注意,没有3
}

generator可以把异步回调代码变成“同步”代码:

// ajax
ajax('http://url-1', data1, function (err, result) {
    if (err) {
        return handle(err);
    }
    ajax('http://url-2', data2, function (err, result) {
        if (err) {
            return handle(err);
        }
        ajax('http://url-3', data3, function (err, result) {
            if (err) {
                return handle(err);
            }
            return success(result);
        });
    });
});

// generator
try {
    r1 = yield ajax('http://url-1', data1);
    r2 = yield ajax('http://url-2', data2);
    r3 = yield ajax('http://url-3', data3);
    success(r3);
}
catch (err) {
    handle(err);
}

你可能感兴趣的:(Javascript)