簡體   English   中英

Javascript平滑方法鏈接

[英]Javascript smooth method chaining

我有一個可以接受某些參數的Web服務,例如?top = 5&orderby = column ---等...

我希望能夠像這樣執行我的對象:

var call = new API();
call.get().top(5).skip(15).orderby("address");

挑戰在於僅通過觸發execute()方法來獲得最后一個訂單。 這是我的代碼。 如果您有更好的主意,請告訴我! 當前每個功能結束時延遲25毫秒,並在下一個功能啟動時停止計時器。 這是適當/可以接受的嗎?


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: {}
};

更新 :你知道嗎? 我將在這一問題上保留我的立場(以下為原始答復)。 考慮到傳遞給setTimeout的回調在JavaScript的單線程事件循環給您的方法鏈“完成”之前永遠不會觸發,您實際上應該沒問題。 (實際上,這還意味着您應該安全地將0傳遞給setTimeout而不是25

我仍然認為您不願意考慮這種設計(如果這是多個開發人員會接觸的代碼,我想說您最好使用更簡單的設計,以減少因過於復雜而造成團隊混亂的風險) ; 但是,如果您堅持走這條路,那么實際上您不應該遇到任何奇怪的Heisenbug。

但是,是的,我支持我的原始建議,即明確要求execute調用。


天啊。 您甚至考慮這個都了! 我的意思是,我的一部分確實為此而愛您(我是駭人聽聞的駭客的忠實擁護者 ); 但事實是,采用這種方法雖然可能最終會奏效,但如果/一旦陷入困境,就會使您發瘋。

我強烈不贊成這樣做的主要原因是,該替代方案非常簡單,並且更重要的是實際上是可靠的 :只需建立execute規則就是實際發送請求的方法,因此任何鏈式方法調用都必須以該方法結尾:

call.get().top(5).skip(15).orderby("address").execute();

如果您對這個基於計時器的想法很感興趣 ,那么可以告訴我您以前從未真正遭受過Heisenbug的折磨(或者,正如我最初猜測的那樣,您只是出於頭腦不清)。

有趣的主意。 雖然,為什么不這樣做呢?

call({ type: "get", top: 5, skip: 15, orderby: "address" });

然后通過遍歷call實現中的對象來處理每個參數,然后發出服務請求。

for(var arg in args) {
    if(args.hasOwnProperty(arg) && args.propertyIsEnumerable(arg)) {
        // process argument
    }
}

這使事情變得簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM