Generator函数

在js中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内

而Generator函数的出现使得打破函数的完整运行成为了可能

generator函数为处理异步编程提供了解决方法(异步函数),内部封装了大量的状态,允许我们逐条遍历

语法:function *demo() { 函数中定义状态 }

  在函数内部通过yield关键字定义状态,yield表示暂停的意思

注意yield关键字只能出现在generator函数中

通过return定义最后一个状态,return后面的状态不会执行

generator函数的返回值实现了next方法,因此可以通过next方法逐条遍历内部的状态

next方法的返回值是一个对象

  done属性: 表示是否遍历完成 value属性: 表示状态值

next 方法返回的状态对象

  如果有状态的情况下,done是fasle,value是状态值

  如果没有状态,此时,done是true,value是undefined

generator函数的返回值也实现了迭代器接口,因此也可以通过for of方式遍历内部的状态

  但是不要同时使用两种方式去遍历内部的状态 因为,一方遍历完成,另一方就得不到状态了

  当generator函数遍历完成之后,此时它的状态变为closed

  当generator函数没有遍历完成的时候,此时它的状态变为suspended

<script>
        function *day() {
            // 定义状态
            yield '起床';
            yield '吃饭';
            yield '工作';
            yield '下班';
            yield '吃晚饭';
            // 最后一个状态可以通过return来定义
            // 注意遍历到return这个状态的时候,done属性也是true
            return '睡觉';
        }
        let t = day(); 
        console.log(t); // day {<suspended>} 返回一个t的对象 suspended表示没有遍历完成的状态 
                可以看出generator函数和普通函数不一样 普通函数调用立即执行并输出返回值 而generator函数返回一个对象
// console.log(t.next()) console.log(t.next()) console.log(t.next()) console.log(t.next()) console.log(t.next()) console.log(t.next()) console.log(t.next()) // for(let item of t) { // // 可以访问yield状态,无法访问return状态 // console.log(item) // } // 一旦遍历完成,只能重新创建再遍历 var d2 = day(); console.log(d2.next()); console.log(d2.next()); </script>

generator函数是异步函数,可以让异步操作一个接一个的触发

function *tast() {
    yield setTimeout(() => {
        console.log(1)
    }, 1000)
    yield setTimeout(() => {
        console.log(2);
    }, 2000)
    yield setTimeout(() => {
        console.log(3);
    }, 3000)
}
// 做这些异步操作
let t = tast();
t.next()
t.next()

generator 函数的数据传递

在generator函数中数据传递有两个方向:

  数据由generator函数的内部流向外部

    1 通过yield表达式定义状态值

    2 在外部通过next方法返回的对象中的value属性获取

  

  数据由generator函数的外部流向内部

    1 在外部通过next方法传递数据 (第一次执行next方法,不需要传递参数)

    2 在内部通过yield表示式接收数据 (想让第一个yield关键字接收数据,要给第二个next方法传递参数)

    

return

  在generator函数的原型中提供了return方法,用于在外部停止内部状态的遍历

  如果在函数体中出现了finally语法,return语句将会延后执行(也就是说return不能终止finally中的语句)

   

throw

在generator函数的原型中提供了throw方法,允许在外部抛出错误

为了代码正常执行,我们可以在状态函数体中通过try catch语句去捕获错误

如果外部抛出两个错误:

  第一个错误在状态函数体中通过try catch语句去捕获第一个错误

  第二个错误在状态函数体外部通过try catch语句去捕获第二个错误

  

yield*

  可以将函数内部的状态复制到另一个函数体中执行

  

三个点语法

  使用三个点语法解构的时候,可以将一个状态函数体中的所有状态值获取到

  

generator 函数的 this

在generator函数中的this指向window 所以,不能通过this去添加任何的属性以及方法

如果想要添加属性或者方法,我们可以在函数执行的时候,使用call或者是apply方法改变其作用域, 将指向函数的原型

  

原文地址:https://www.cnblogs.com/yess/p/14710547.html