Generator 异步实现同步化

253 阅读1分钟

总结:

next() 方法返回一个包含属性 done 和 value 的对象:如果迭代器超过迭代序列的末尾,则值为 true return() 方法返回给定的值并结束生成器。 throw() 方法用来向生成器抛出异常,并恢复生成器的执行,返回带有 done 及 value 两个属性的对象。

  function* gen() {
        debugger
        yield 1;      
        debugger
        yield 2;      
        debugger
        yield 3;
      }

      var g = gen();
      debugger
      console.log(g.next()) // { value: 1, done: false }
      debugger
      console.log(g.return("foo"))  // { value: "foo", done: true }
      debugger
      console.log(g.next())       // { value: undefined, done: true }

      function* gen() {
        while(true) {
          try {
            debugger
            yield 42;
          } catch(e) {
            debugger
            console.log("Error caught!");
          }
        }
      }

      var g = gen();
      debugger
      g.next(); // { value: 42, done: false }
      debugger
      g.throw(new Error("Something went wrong")); // "Error caught!"

1、最基础的generator函数使用方法:

2、异步generator函数使用方法:

    function pro (){
      return new Promise((resolve)=>{
        debugger
        setTimeout(()=>{
          console.log('b')
          resolve()
      },0)
      })
    }
    function* func1(){
      debugger
      console.log('a')
      // setTimeout(()=>{
      //   console.log('b')
      // },0)
      yield pro();
      debugger
      console.log('c')
    }
    let g = func1()

    g.next().value.then(()=>{
      debugger
      g.next()
    })

3、带返回参数

    function *withReturn() {
      let x = yield 1;
      return x + 2;
    }

    let func = withReturn();
    func.next();
    // -> {value: 1, done: false}
    func.next(1);
    // -> {value: 3, done: true}
    func.next();
    // -> {value: undefined, done: true

4、generator的应用场景

至关重要的run函数



const run = (fn) => {
    const gen = fn();
    const next = (data) => {
        // 第一次传递的data undefined
        const result = gen.next(data);
        if (result.done) return;
        // 只要保证genrator 内部 yield 出来的东西是函数即可
        // yield 出来的是一个函数,接受另一个函数作为参数
        // 也就达到了顺序执行的目的
        result.value(next);
    }
    next();
};
var getList1 = (success) => {
    $.ajax({
        url: 'http://sapi.bbeeii.com/martgoods/category/fightgroup.html',
        type: 'GET',
        dataType: 'jsonp',
        jsonpCallback: 'bbeeiiMartgoodsCategoryGet',
        success
    });
};
var getList2 = (success) => {
    $.ajax({
        url: 'http://sapi.bbeeii.com/martshow/1-15----1.html',
        type: 'GET',
        dataType: 'jsonp',
        jsonpCallback: 'bbeeiiMartshowGet',
        success
    });
};
var genFunc = function*() {
    // 注意a/b,是通过 上面的data传进来的东西(而不是函数的返回值)
    // 写惯了异步,还是非常不习惯的
    var a = yield getList1;
    var b = yield getList2;
    console.log(a, b);
};
run(genFunc);
run(function * () {
    var a = yield (callback) => {
        setTimeout(() => {
            alert(1);
            callback(2);
        }, 1000);
    }

    var b = yield (callback) => {
        setTimeout(() => {
            console.log(a, b);
            var c = a + b;
            callback(c);
        }, 3000);
    }
    console.log(a, b);
});

异步

回调函数 事件监听 发布/订阅 Promise 对象 async/await generator/yeild