javascript 支持链式调用的异步调用框架Async.Operation

复制代码 代码如下:

  Async = {};

  Async.Operation = function(options) {

  options = options || {};

  var callbackQueue = [];

  var chain = (options.chain && options.chain === true) ? true : false;

  var started = false;

  var innerChain = null;

  this.result = undefined;

  this.state = "running";

  this.completed = false;

  this.yield = function(result) {

  var self = this;

  if (!chain) {

  self.result = result;

  self.state = "completed";

  self.completed = true;

  } else {

  started = true;

  self.result = result;

  self.state = "chain running";

  self.completed = false;

  }

  setTimeout(function() {

  if (!innerChain) {

  while (callbackQueue.length > 0) {

  var callback = callbackQueue.shift();

  if (chain) {

  callbackResult = callback(self.result);

  self.result = callbackResult;

  if (callbackResult && callbackResult instanceof Async.Operation) {

  innerChain = Async.chain();

  while (callbackQueue.length > 0) {

  innerChain.next(callbackQueue.shift());

  }

  innerChain.next(function(result) {

  self.result = result;

  self.state = "completed";

  self.completed = true;

  return result;

  });

  callbackResult.addCallback(function(result) {

  self.result = result;

  innerChain.go(result);

  });

  }

  } else {

  callback(self.result);

  }

  }

  if (!innerChain) {

  self.state = "completed";

  self.completed = true;

  }

  } else {

  while (callbackQueue.length > 0) {

  innerChain.next(callbackQueue.shift());

  }

  innerChain.next(function(result) {

  self.result = result;

  self.state = "completed";

  self.completed = true;

  return result;

  });

  }

  }, 1);

  return this;

  };

  this.go = function(initialArgument) {

  return this.yield(initialArgument);

  }

  this.addCallback = function(callback) {

  callbackQueue.push(callback);

  if (this.completed || (chain && started)) {

  this.yield(this.result);

  }

  return this;

  };

  this.next = function(nextFunction) {

  return this.addCallback(nextFunction);

  };

  };

  Async.chain = function(firstFunction) {

  var chain = new Async.Operation({ chain: true });

  if (firstFunction) {

  chain.next(firstFunction);

  }

  return chain;

  };

  Async.go = function(initialArgument) {

  return Async.chain().go(initialArgument);

  }