我有一个可以接受某些参数的网络服务,例如?top = 5& orderby = column --- etc ......
我希望能够像这样执行我的对象:
var call = new API();
call.get().top(5).skip(15).orderby("address");
挑战是只让最后一个orderby触发execute()方法。这是我的代码。如果您有任何更好的想法,请告诉我!当每个函数结束时,它当前延迟25ms,并在下一个函数启动时停止计时器。这是正确/可接受的吗?
var API = function (webservice) {
this.webservice(webservice);
return this;
};
API.prototype = {
version: function (urlFormat) {
if (urlFormat) {
return "v" + urlFormat.split('.').join('_');
}
return sessionStorage.getItem("version");
},
path: function () {
return "../WebAPI/";
},
execute: function () {
var path = this.path() + this.webservice() + ".svc/";
if (this.__parameters) {
path += "?";
}
var first = true;
for (var k in this.__parameters) {
if (k !== "type")
path += ((first) ? (function(){first = false; return ""})() : "&") + "$" + k + "=" + this.__parameters[k];
};
console.log(this.__parameters.type + ": " + path);
return this;
},
put: function () {
this.doIt("type","put");
return this;
},
post: function () {
this.doIt("type","post");
return this;
},
get: function() {
this.doIt("type","get");
return this;
},
delete: function() {
this.doIt("type","delete");
return this;
},
toString: function () {
return "API";
},
webservice: function(webservice) {
if (webservice) {
this.__webservice = webservice;
}
else {
return this.__webservice;
}
},
top: function (p) {
this.doIt("top",p);
return this;
},
view: function (p) {
this.doIt("view",p);
return this;
},
orderby: function (p) {
this.doIt("orderby",p);
return this;
},
criteria: function (p) {
this.doIt("criteria",p);
return this;
},
skip: function (p) {
this.doIt("skip",p);
return this;
},
filter: function (p) {
this.doIt("filter",p);
return this;
},
doIt: function (method, parameter) {
this.__timerStop();
this.__parameters[method] = parameter;
this.__timerStart();
},
__timerStop: function () {
if (this.__timer) {
clearTimeout(this.__timer);
}
},
__timerStart: function (append) {
var self = this;
if (this.__timer) {
this.__timerStop();
}
this.__timer = setTimeout(function() {
console.log("executing.");
console.log(JSON.stringify(self.__parameters));
self.execute();
}, 25);
},
__parameters: {}
};
答案 0 :(得分:6)
更新:你知道吗?我要在这个问题上软化我的立场(下面的原始答案)。实际上你应该没问题,因为你传递给setTimeout
的回调在给定JavaScript的单线程事件循环之前,在方法链“完成”之前永远不会触发。 (事实上,这也意味着你应该安全地将0
传递给setTimeout
而不是25
。)
我仍然认为你想到这个设计是疯了(如果这是多个开发人员会触及的代码,我会说你的设计更简单,只是为了减少团队混淆的风险。过度复杂);但如果你坚持走这条路,你实际上不应该遇到任何奇怪的Heisenbugs。
但是,我坚持原来的建议,明确要求execute
来电。
哦,伙计。你是疯狂甚至考虑到这一点!我的意思是,我的一部分确实爱你(我是big fan of horrifying hacks);但事实是,采用这种方法,而可能最终会起作用,如果/当它变得混乱时,会让你疯狂。
我强烈反对的主要原因是替代方案非常容易,更重要的是,实际上可靠:只需建立execute
的规则是实际发送请求的方法,因此任何链式方法调用都必须以:
call.get().top(5).skip(15).orderby("address").execute();
如果你真的爱上这个基于计时器的想法,有些东西告诉我你以前从来没有真正受过Heisenbug(或者,正如我原先猜测的那样,你只是在你脑海中)。
答案 1 :(得分:1)
有趣的想法。虽然,为什么不这样做呢:
call({ type: "get", top: 5, skip: 15, orderby: "address" });
然后通过循环遍历call
实现中的对象来处理每个参数,然后发出服务请求。
for(var arg in args) {
if(args.hasOwnProperty(arg) && args.propertyIsEnumerable(arg)) {
// process argument
}
}
这使事情变得简单。