0

?top = 5&orderby =column---などの特定のパラメーターを受け取ることができるWebサービスがあります。

次のようにオブジェクトを実行できるようにしたい:

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

課題は、execute()メソッドをトリガーする最後のorderbyのみを使用することです。これが私のコードです。もっと良いアイデアがあれば教えてください!現在、各機能が終了すると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: {}
};
4

2 に答える 2

6

更新:あなたは何を知っていますか?私はこれに対する私のスタンスを和らげるつもりです(以下の元の答え)。setTimeoutJavaScriptのシングルスレッドイベントループが与えられた場合、メソッドチェーンが「完了する」前に、渡すコールバックが起動することは決してないことを考えると、実際には問題ないはずです。0(実際、これは、setTimeout代わりに安全に渡す必要があることも意味します25。)

私はまだあなたがこのデザインを考えるのが難しいと思います(そしてこれが複数の開発者が触れるコードである場合、過度の複雑さによるチームの混乱のリスクを減らすために、よりシンプルなデザインを使用する方が良いと思います) ; しかし、この道を進むことを主張するのであれば、実際には奇妙な特異なバグに遭遇するべきではありません。

しかし、ええ、私はexecute明示的に電話を要求することについての私の最初のアドバイスを支持します。


ちょっと、あなた。あなたもこれを検討することに夢中です!つまり、私の一部はあなたを愛しています(私は恐ろしいハックの大ファンです); しかし、実際には、このアプローチを採用することは、最終的には機能する可能性がありますが、それがうまくいかない場合は、あなたを狂わせるでしょう。

私が強くお勧めしない主な理由は、代替手段が非常に簡単で、さらに重要なことに、実際に信頼できることです。実際に要求を送信するメソッドであるルールを確立するだけなexecuteので、連鎖メソッド呼び出しは次のように終了する必要があります。

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

このタイマーベースのアイデアに真剣に夢中になっている場合は、これまでにHeisenbugに実際に苦しんだことは一度もないと言われます(または、最初に推測したように、あなたは気が狂っています)。

于 2012-05-15T21:11:13.840 に答える
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
    }
}

これにより、物事がシンプルになります。

于 2012-05-15T21:44:13.410 に答える