我正在寻找一个允许我轻松地将方法链接在一起的库,但推迟执行,直到在链中进一步提供参数:
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()
这就是为什么我正在寻找一个可能有更成熟的想法来实现这个目标的库:)
答案 0 :(得分:2)
这篇文章讨论了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构建解决方法。
对于类似的某些实现,您可以看到this question我在哪里实现类似的东西。
Promises tutorial - 承诺允许您使用这种称为CPS(延续传递样式)的执行效果很好。
Bluebird - 最快,最可能最好的承诺库。
Q - 可能是用于在JavaScript中链接执行和承诺的最知名且最广泛使用的库。我自己多次使用它。
How does basic chaining work in JavaScript - SO中的另一个相关问题。
答案 1 :(得分:0)
请注意,您一定会找到一个全面的解决方案。
看起来你正在寻找一种通用的解决方案来解决那些需要已经融入库中的问题。我的意思是,我确信有些库具有这种功能,但它们不会自动地在其他库上挂钩(假设它们已经专门为你想要定位的库的正确版本实现了覆盖,可能)。
但是,在某些情况下,您可能需要查看Stream.js库,这可能涵盖了足够的数据相关案例,以使您感兴趣:
答案 2 :(得分:0)
我不知道是否有用于构建此类方法的库,但您可以自己轻松构建该功能。基本上,它将是一个具有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
}
};
这是构建fluent interface的标准方法。当然,你也可以创建一个辅助函数,你传递一个方法名称到设置的映射,如果它太冗长就会为你编写方法: - )
答案 3 :(得分:0)
您需要一个队列来维护方法链的异步和同步。
这是一个使用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;
}
答案 4 :(得分:-3)
正如@Jordan Doyle在comment中所说的那样:
只需返回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();