zoukankan      html  css  js  c++  java
  • 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方法改变其作用域, 将指向函数的原型

      

  • 相关阅读:
    [刷题] PTA 7-32 说反话-加强版
    [算法] 堆
    [笔记] 《c++ primer》显示器程序 Chapter7
    [笔记] 《c++ primer》书店程序 Chapter7
    [c++] <vector>
    [笔记] 《c++ primer》书店程序 Chapter2
    [笔记] 《c++ primer》书店程序 Chapter 1
    253. Meeting Rooms II
    461. Hamming Distance
    252. Meeting Rooms
  • 原文地址:https://www.cnblogs.com/yess/p/14710547.html
Copyright © 2011-2022 走看看