Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

初探Generator #1

Open
For-me opened this issue Nov 24, 2017 · 0 comments
Open

初探Generator #1

For-me opened this issue Nov 24, 2017 · 0 comments

Comments

@For-me
Copy link
Owner

For-me commented Nov 24, 2017

Generator是ES6中新增的数据类型,其主要目的是通过一段程序,来持续被迭代或枚举出符合某个公式或算法的有序数列中的元素,其根本是一种特殊的 iterator,提供的next方法可以接收一个参数并且返回值取决于它的构造函数 => generator function,同时其拥有thorw方法用于异常处理


什么是generator function?

此函数内可以使用yield关键字来交出函数的执行权,在yield出现的地方可以通过generatornextthrow方法向外界传递值,并且generator函数通过function *声明

那么为什么会出现generator函数呢?

究其根本是为了变相实现同步的目的(因为JavaScripts是单线程的),与Promise间的区别在于Promise是为了回调的形式去处理逻辑。ES7规范中async才是真正意义上的异步回调

下面是示例

普通函数:

function fib(max) {
  var t,
        a = 0,
        b = 1,
       arr = [0, 1];
       while (arr.length < max){
            [a, b] = [b, a + b]
            arr.push(b);
}
         return arr;
}
//测试
fib(5); //[0,1,1,2,3]

generator函数:

function* fib(max) {
  var t,
        a = 0,
        b = 1,
        n = 0;
       while (n <max){
           yield a;
          [a, b] = [b, a + b];
          n++;
   }
     return;
}
//测试
var f = fib(5);
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: false}
f.next(); // {value: undefined, done: true}

如上示例,next()方法会执行generator代码,每次遇到yiled x,都会返回对象{value: x, done: true/false},然后暂停。返回的value就是yield的返回值,done表示generator代码是否已执行完毕。如果donetrue,则value就是return返回值

那么generator在实际中的应用?

我们来看这段代码

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

很显然,上面这段代码是我们在业主中很容易遇到的,嵌套请求。。如果请求数更多的话是不是要写更多的嵌套呢,这样看起来一点也不优雅,也不利于维护。那么我们怎么办呢?

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

是不是更精炼了呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant