除非您愿意序列化 AJAX,否则我无法想到其他方法来完成您所建议的操作。话虽这么说,我认为您所拥有的相当不错,但您可能需要稍微清理一下结构,以免用初始化数据创建的对象乱七八糟。
这是一个可能对您有帮助的函数:
function gate(fn, number_of_calls_before_opening) {
return function() {
arguments.callee._call_count = (arguments.callee._call_count || 0) + 1;
if (arguments.callee._call_count >= number_of_calls_before_opening)
fn.apply(null, arguments);
};
}
该函数就是所谓的高阶函数,即以函数作为参数的函数。这个特定的函数返回一个函数,该函数在被调用时调用传递的函数number_of_calls_before_opening
次。例如:
var f = gate(function(arg) { alert(arg); }, 2);
f('hello');
f('world'); // An alert will popup for this call.
您可以使用它作为回调方法:
foo.bar = function() {
var callback = gate(this.method, 2);
sendAjax(new Request(), callback);
sendAjax(new Request(), callback);
}
第二个回调,无论它是什么,都会确保method
叫做。但这会导致另一个问题:gate
函数在没有任何上下文的情况下调用传递的函数,意思是this
将引用全局对象,而不是您正在构造的对象。有几种方法可以解决这个问题:您可以关闭this
通过将其别名为me
or self
。或者你可以创建another高阶函数就可以做到这一点。
第一种情况如下所示:
foo.bar = function() {
var me = this;
var callback = gate(function(a,b,c) { me.method(a,b,c); }, 2);
sendAjax(new Request(), callback);
sendAjax(new Request(), callback);
}
在后一种情况下,另一个高阶函数将如下所示:
function bind_context(context, fn) {
return function() {
return fn.apply(context, arguments);
};
}
该函数返回一个在传递的上下文中调用传递的函数的函数。其示例如下:
var obj = {};
var func = function(name) { this.name = name; };
var method = bind_context(obj, func);
method('Your Name!');
alert(obj.name); // Your Name!
从长远来看,您的代码将如下所示:
foo.bar = function() {
var callback = gate(bind_context(this, this.method), 2);
sendAjax(new Request(), callback);
sendAjax(new Request(), callback);
}
无论如何,一旦进行了这些重构,您就已经清除了正在构造的对象,其中包含仅初始化所需的所有成员。