我希望得到类似的功能:
function foo(before, after){
before();
setTimeout(function(){
after();
},100)
}
foo(function(){
console.log('before');
}, function(){
console.log('after');
});
返回对象而不是使用回调(伪代码)时:
var foo = function() {
before();
setTimeout(function(){
after();
},100)
return {
before: before,
after: after
}
};
foo().before(function(){
console.log('before');
});
foo().after(function(){
console.log('after');
});
或者甚至
foo().before(function(){
console.log('before');
}).after(function(){
console.log('after');
});
这可能吗?
答案 0 :(得分:4)
是的,您的函数可以使用before
和after
方法返回一个对象,该方法可以跟踪已设置的回调,当两者都设置时,它可以调用它们:
function foo() {
var beforeFunc = null, afterFunc = null;
function activate() {
beforeFunc();
window.setTimeout(afterFunc, 100);
}
var obj = {
before: function(f) {
beforeFunc = f;
if (afterFunc != null) activate();
return obj;
},
after: function(f) {
afterFunc = f;
if (beforeFunc != null) activate();
return obj;
}
};
return obj;
}
// As both callbacks need to be set, the order is not important
foo().after(function(){
console.log('After');
}).before(function(){
console.log('Before');
});
答案 1 :(得分:2)
几乎可能。
您提议的使用示例存在的问题是,在foo()
或before
回调指定之前调用after
。同时,在您的示例实现中,这些回调在foo
内执行。所以 无法实现:在该方法已经运行之后,您无法追溯更改方法中发生的事情。
如果您真正想要的是通过foo
提供的回调立即执行几乎 - 即,如果纯同步执行不是强制性的 - 您可以得到你的'通过简单的setTimeout
电话后重新开始:
function foo() {
var callbacks = {
before: function() {},
after: function() {}
};
setTimeout(function() {
callbacks.before();
setTimeout(callbacks.after, 100);
}, 0);
return {
before: function(callback) {
callbacks.before = callback;
return this;
},
after: function(callback) {
callbacks.after = callback;
}
};
}
此处,foo()
将返回一个对象,该对象公开方法以修改callbacks
方法体内关闭的foo
对象。然后,这些方法将用于事件循环的下一个时钟, foo()
执行后。
如果您有兴趣查看此代码,我已创建an example at JSBin。
答案 2 :(得分:1)
function foo(){};
foo.prototype.before = function(f){ this._before = f };
foo.prototype.after = function(f){ this._after = f };
foo.prototype.go = function(){
this._before();
setTimeout(this._after,100);
}
var f = new foo;
f.before(function(){ … });
f.after(function(){ … });
f.go();
但话又说回来,你可能会更简单:
function foo(){};
foo.prototype.go = function(){
this.before();
setTimeout(this.after,100);
}
var f = new foo;
f.before = function(){ … };
f.after = function(){ … };
f.go();
答案 3 :(得分:1)
这是另一种变体:
var createFooBuilder = function () {
var before = function() {};
var after = function() {};
var func = function () {
before();
setTimeout(function () {
after();
}, 100)
};
func.before = function(value) {
before = value;
return func;
}
func.after = function(value) {
after = value;
return func;
}
return func;
};
var foo = createFooBuilder();
foo.before(function () {
console.log('before');
}).after(function () {
console.log('after');
});
foo();
我当然建议您尝试让jQuery Deferred为您工作,然后您可以拥有后续功能列表。
答案 4 :(得分:1)
Phrogz的答案很好,但是你也可以在没有原型的情况下做到这一点:
function foo() {
ret = function () { return ret.call(); };
ret.call = function () {
this._before();
setTimeout(this._after,100);
};
ret.before = function (x) { this._before = x; return this; };
ret.after = function (x) { this._after = x; return this; };
return ret;
};
test = foo().before(function(){
console.log('before');
}).after(function(){
console.log('after');
});
通话:
test();
做你期望的事。