2015-12-05 28 views
2

林試圖寫一個包裝用於鏈式方法:包裝保存方法的結果

new Example().child("First").child("Second").read(function(name){console.log(name)}) 

該包裝應該保存的第一執行的結果。下一次包裝被調用它不應該執行原來的方法同樣的方法,它應該返回所保存的結果

wrapper = new Wrapper(); 
//this time the result of the passed method gets saved 
wrapper.wrap(new Example().child("First").child("Second").read, function(name){console.log(name)}) 
//now it should return the saved value 
wrapper.wrap(new Example().child("First").child("Second").read, function(name){console.log(name)}) 

我想要實現此功能調用數據庫庫。當設備沒有互聯網連接時,它應該從保存的包裝狀態中讀取。

我實現這樣的包裝:

Wrapper = function() { 
    this.saved_funcs = {} 
} 

Wrapper.prototype.wrap = function (func, callbac) { 
    if (func in this.saved_funcs) { 
     callbac(this.saved_funcs[func]); 
    } else { 
     func(function (result) { 
      this.saved_funcs[func] = result; 
      callbac(result); 
     }.bind(this)) 
    } 
}; 

http://jsfiddle.net/boaLf6s3/1/

但是,當我執行的包裝則返回undefined?我的示例將始終存儲整個代碼以檢查方法是否已觸發。 這就是爲什麼我想問你如何實現這樣一個包裝?謝謝

回答

1

您嘗試引用的函數需要從對象的上下文執行,因爲它使用this。是更好,如果你只是傳遞的對象,然後調用read代替:

Example = function(){ 
 
\t this.text = ""; 
 
} 
 

 
Example.prototype.child = function(name){ 
 
\t this.text += name + " " + name; 
 
\t return this; 
 
} 
 

 
Example.prototype.read = function(callbac){ 
 
\t callbac(this.text); 
 
} 
 

 

 

 
Wrapper = function(){ 
 
\t this.saved_funcs = {} 
 
} 
 

 

 
Wrapper.prototype.wrap = function(obj, callbac){ 
 
\t if(obj.read in this.saved_funcs){ 
 
\t \t callbac(this.saved_funcs[obj.read]); 
 
\t }else{ 
 
\t \t obj.read(function(result){ 
 
\t \t \t this.saved_funcs[obj.read] = result; 
 
\t \t \t callbac(result); 
 
\t \t }.bind(this)) 
 
\t } 
 
}; 
 

 

 

 
new Example().child("First").child("Second").read(function(name){document.getElementById("normal").innerHTML = name}) 
 

 

 
wrapper = new Wrapper(); 
 

 
wrapper.wrap(new Example().child("First").child("Second"), function(name){console.log(name)}) 
 

 
wrapper.wrap(new Example().child("First").child("Second"), function(name){ document.getElementById("saved").innerHTML = name })
<h2> 
 
    Normal Result 
 
</h2> 
 
<p id="normal"> 
 
    
 
</p> 
 
<h2> 
 
    Saved Result 
 
</h2> 
 
<p id="saved"> 
 
    
 
</p>

或者你可以結合你的函數是這樣的:

Example = function(){ 
 
\t this.text = ""; 
 
} 
 

 
Example.prototype.child = function(name){ 
 
\t this.text += name + " " + name; 
 
\t return this; 
 
} 
 

 
Example.prototype.read = function(callbac){ 
 
\t callbac(this.text); 
 
} 
 

 

 

 
Wrapper = function(){ 
 
\t this.saved_funcs = {} 
 
} 
 

 

 
Wrapper.prototype.wrap = function(func, callbac){ 
 
\t if(func in this.saved_funcs){ 
 
\t \t callbac(this.saved_funcs[func]); 
 
\t }else{ 
 
\t \t func(function(result){ 
 
\t \t \t this.saved_funcs[func] = result; 
 
\t \t \t callbac(result); 
 
\t \t }.bind(this)) 
 
\t } 
 
}; 
 

 

 

 
new Example().child("First").child("Second").read(function(name){document.getElementById("normal").innerHTML = name}) 
 

 

 
wrapper = new Wrapper(); 
 

 
var child = new Example().child('First').child('Second'); 
 
var read = child.read.bind(child); 
 

 
wrapper.wrap(read, function(name){console.log(name)}) 
 

 
wrapper.wrap(read, function(name){ document.getElementById("saved").innerHTML = name })
<h2> 
 
    Normal Result 
 
</h2> 
 
<p id="normal"> 
 
    
 
</p> 
 
<h2> 
 
    Saved Result 
 
</h2> 
 
<p id="saved"> 
 
    
 
</p>