代码改变世界

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

2009-06-30 18:05 by Cat Chen, ... 阅读, ... 评论, 收藏,  编辑
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);
}