美文网首页
03-JavaScript-Generator异步编程

03-JavaScript-Generator异步编程

作者: 低头看云 | 来源:发表于2020-10-23 16:43 被阅读0次

    Generator

    概念

    • Generator 函数是 ES6 提供的一种异步编程解决方案
    • Generator 函数是一个状态机,封装了多个内部状态。
    • Generator 还是一个遍历器对象生成函数.返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

    形式上

    Generator 函数是一个普通函数,但是有两个特征。

    • 一是,function关键字与函数名之间有一个星号
    • 二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    var hw = helloWorldGenerator();
    // --- 输出 ------
    console.log(hw.next()) // { value: 'hello', done: false }
    console.log(hw.next()) // { value: 'world', done: false }
    console.log(hw.next()) // { value: 'ending', done: true }
    console.log(hw.next()) // { value: undefined, done: true }
    

    例子

    // 执行顺序
    function* test(x) {
      console.log(111)
      let a = yield x + 222
    
      console.log('a', a)
      let b = yield 333 + a
    
      console.log('b', b)
      let c = yield 44444 + b
    
      console.log('c', c)
    }
    
     
    let t = test(1)
    
    console.log(t.next())
    console.log(t.next())
    console.log(t.next())
    console.log(t.next())
    
    /**
    111
    { value: 223, done: false }
    a undefined
    { value: NaN, done: false }
    b undefined
    { value: NaN, done: false }
    c undefined
    { value: undefined, done: true }
    **/
    

    发现除了第一个next()能正常输出{ value: 223, done: false },第二个next开始输出 a=undefined.

    查阅文档后发现

    yield表达式本事是没有返回值, 或者说总是返回undefined.

    但是, next 方法可以带一个参数, 该参数会被当做上一个yield表达式的返回

    • 给next方法传递参数
    // 执行顺序
    function* test(x) {
      console.log(111)
      let a = yield x + 222
    
      console.log('a', a)
      let b = yield 333 + a
    
      console.log('b', b)
      let c = yield 44444 + b
    
      console.log('c', c)
    }
    
    
    let t = test(1)
    
    console.log(t.next())
    //111
    // { value: 223, done: false }
    
    // next 方法的参数
    // yield表达式本身没有返回值,或者说总是返回undefined。
    // next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
    console.log(t.next(33))
    // a 33
    // { value: 366, done: false }
    
    console.log(t.next('cc'))
    //b cc
    // { value: '44444cc', done: false }
    
    console.log(t.next('dd'))
    // c dd
    // { value: undefined, done: true }
    
    

    generator函数的运行顺序如下:

    image-20201023154710301

    generator搭配promise将异步回调变成同步模式

    function request(data) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(it.next(data + 1))
        }, 1000)
      })
    }
    
    function* getApi() {
      let res1 = yield request(1)
      console.log('res1', res1)
      let res2 = yield request(res1)
      console.log('res2', res2)
      let res3 = yield request(res2)
      console.log('res3', res3)
    }
    
    let it = getApi()
    it.next()
    
    // res1 2
    // res2 3
    // res3 4
    

    相关文章

      网友评论

          本文标题:03-JavaScript-Generator异步编程

          本文链接:https://www.haomeiwen.com/subject/sbgvmktx.html