[英]Does anyone know of a JS Chaining library that allows for deferred execution of methods?
我正在尋找一個允許我輕松地將方法鏈接在一起的庫,但推遲執行,直到在鏈中進一步提供參數:
chain
.scanDirectory ( '/path/to/scan' )
.recursively()
.for ( /\.js$/i )
.cache()
.provideTo ( '0.locals' )
.as ( 'scripts' )
.defer();
重要的是scanDirectory
函數背后的代碼實際上沒有被調用,直到它被定義為應該遞歸並尋找.js
文件。
我不太確定如何邏輯設置它以便我可以做類似的事情:
chain
.scanDirectory( '/path/to/scan' )
.scanDirectory( '/another/path' )
.for ( /\.js$/i ) // provided to both paths above?
.doSomethingElse()
這就是為什么我正在尋找一個可能有更成熟的想法來實現這個目標的庫:)
這篇文章討論了JS中的執行類型,最后有相關庫的鏈接
在JS中有兩種類型的執行:
同步,您可以將操作和參數推送到隊列結構,並使用.run
命令運行它們。
你可以這樣做:
var chain = function(){
var queue = []; // hold all the functions
function a(param){
//do stuff, knowing a is set, may also access other params functions set
}
return {
a:function(someParam){
queue.push({action:a,param:someParam});
return this;
},
... // more methods
run:function(){
queue.forEach(function(elem){ // on each item
elem.action.apply(null,param);//call the function on that item
});
}
};
}
當你調用run
,這將執行隊列中的所有函數,語法就像這樣
chain().a(15).a(17).run();
你可以簡單地設置一個超時,你不需要使用像.run
這樣的東西。
var chainAsync = function(){//不需要隊列
function a(param){
//do stuff, knowing a is set, may also access other params functions set
}
return {
a:function(someParam){
setTimeout(a,0,someParam);
return this;
},
... // more methods
};
}
用法就像是
chain().a(16).a(17);
如果要在函數之間共享參數,可以將它們存儲在對象本身的某個位置(除隊列外還有var state
)。
它是同步或異步。 您無法通過上下文檢測其中一個。 正在為ES6構建解決方法。
對於某些類似的實現,您可以在我實現類似的東西時看到這個問題 。
Promises教程 - promises讓你使用這種類型的執行稱為CPS(延續傳遞樣式),效果很好。
關於承諾的另一個好帖子 。
藍鳥 - 最快,最可能最好的承諾庫。
問 :可能是最着名和最廣泛使用的庫,用於鏈接JavaScript中的執行和承諾。 我自己用了好幾次。
基本鏈如何在JavaScript中工作 - 這里的另一個相關問題。
請注意,您一定會找到一個全面的解決方案。
看起來你正在尋找一種通用的解決方案,這些解決方案需要已經融入庫中。 我的意思是,我確信有些庫具有這種功能,但它們不會自動地在其他庫上掛鈎(假設它們已經專門為你想要定位的庫的正確版本實現了覆蓋,可能)。
但是,在某些情況下,您可能需要查看Stream.js庫,它可能涵蓋了足夠的數據相關案例,以使您感興趣:
我不知道是否有用於構建此類方法的庫,但您可以自己輕松構建該功能。 基本上,它將是一個具有setter方法和一個execute
函數的設置對象(在您的情況下, defer
)。
function Scanner() {
this.dirs = [];
this.recurse = false;
this.search = "";
this.cache = false;
this.to = "";
this.name = "";
}
Scanner.prototype = {
scanDirectory: function(dir) {
this.dirs.push(dir);
return this,
},
recursively: function() {
this.recurse = true;
return this;
},
for: function(name) {
this.search = name;
return thsi;
},
cache: function() {
this.cache = true;
return this;
},
provideTo: function(service) {
this.to = service;
return this;
},
as: function(name) {
this.name = name;
return this;
},
defer: function() {
// now, do something with all the given settings here
},
doSomethingElse: function() {
// now, do something else with all the given settings here
}
};
這是構建流暢界面的標准方法。 當然,你也可以創建一個輔助函數,你傳遞一個方法名稱到設置的映射,如果它太冗長就會為你編寫方法:-)
您需要一個隊列來維護方法鏈的異步和同步。
這是一個使用jQuery.queue的實現,我為一個項目做了:
function createChainable(options) {
var queue = [];
var chainable = {
method1 : function () {
queue.push(function(done){
// code here
done();
});
return chainable;
},
exec1 : function () {
queue.push(function(done){
// code here
done();
});
$.queue(ELEMENT, QUEUE_NAME, queue).dequeue(QUEUE_NAME);
return chainable;
}
};
return chainable;
}
正如@Jordan Doyle在評論中所說:
剛回到this
因此,對象中的每個方法都應該返回return語句中的對象,以便您可以鏈接另一個方法。
例如:
var obj = new (function(){
this.methOne = function(){
//...
return this;
}
this.methTwo = function(){
//...
return this;
}
this.methThree = function(){
//...
return this;
}
})();
//So you can do:
obj.methOne().methTwo().methThree();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.