SOURCE

// function runYield(generator) {
//   var iterator = generator();
//   callRecusion(iterator, undefined);
// }
// function callRecusion(it, value) {
//   var next = it.next(value);
//   var value = next.value;
//   var done = next.done;
//   if (!done) {
//     Promise.resolve(value).then(function(result) {
//       callRecusion(it, result);
//     })
//   }
// }
// function* g() {
//   var a = yield 2;
//   console.log(a);
//   var c = yield new Promise(function(res) {
//     res(111);
//   });
//   console.log(c);
//   var b = yield 3;
// }
// runYield(g)
// function runCallback(generator) {
//   var iterator = generator();
//   callRecusion(iterator, undefined);
// }
// function callRecusion(it, value) {
//   var next = it.next(value);
//   var value = next.value;
//   var done = next.done;
//   if (done) {
//     return;
//   }
//   if (typeof value === 'function') {
//     value(function(v) {
//       callRecusion(it, v);
//     })
//   } else {
//     callRecusion(it, value);
//   }
// }
// function* g() {
//   var a = yield 111;
//   var b = yield function(fn) {
//     setTimeout(function() {
//       fn(1000);
//     }, 1000);
//   }
//   console.log(b);
// }
// runCallback(g)
function noop() {

}

// 观察者模式
function Observable(generator) {
  this._generator = generator;
}

Observable.prototype.subscribe = function(observer) {
  observer = new Observer(observer);
  this._generator.call(this, observer);
}

function Observer(observer) {
  this._raw = observer;
  this._complete = false;
  this.observer = {};
  this.normalize(observer);
  this._proxy();
}

Observer.prototype.normalize = function(observer) {
  var thiz = this;
  if (typeof observer === 'object') {
    this.observer = {
      next: function() {
        if (!thiz._complete) {
          return observer.next ? observer.next.apply(thiz, arguments) : noop();
        }
      },
      complete: function() {
        thiz._complete = true;
        return observer.complete ? observer.complete.apply(thiz, arguments) : noop();
      },
      error: observer.error || noop
    };
    return;
  }
  var args = [].slice.call(arguments);
  this.observer = {
    next: args[0] && typeof args[0] === 'function' ? args[0].bind(thiz) : noop(),
    complete: args[1] && typeof args[1] === 'function' ? args[1].bind(thiz) : noop(),
    error: args[2] && typeof args[2] === 'function' ? args[2].bind(thiz) : noop()
  };
};

Observer.prototype._proxy = function() {
  for (let key in this.observer) {
    if (this.observer.hasOwnProperty(key)) {
      Object.defineProperty(this, key, {
        get: function() {
          return this.observer[key];
        }
      });
    }
  }
}

Observable.create = function(generator) {
  return new Observable(generator);
}


var ob = Observable.create(function(observer) {
  	console.log(observer)
    observer.next(1);
    observer.next(2);
    observer.complete();
    observer.next(3);
});

ob.subscribe({
    next: function(data) {
        console.log(data);
    },
    complete: function() {
        console.log('complete');
    },
    error: function(error) {
        console.log(error);
    }
});
console 命令行工具 X clear

                    
>
console