4

Node.js を使用して、スクリプト可能な URL リダイレクトを処理しようとしています。非常にうまく機能していますが、スクリプトは他の人が管理するため、できるだけ単純な形式にする必要があります。

私がやりたいのは、ビルダーパターンを使用して、次のようなものを作成できるようにすることです。

redirectWhen.isMobileDevice().urlMatches("http://www.somewhere.com").thenGoTo("http://mobile.somewhere.com");
redirectWhen.urlMatches("http://subdomain.somewhere.com").thenGoTo("http://www.somewhere.com/somefolder/");

次に、結果に基づいてリダイレクトします (基本的に、チェーン内のすべてのアイテムに一致した最後のものが勝ちます)。すべての関数 ( isMobileDevice()&urlMatches(...)いくつかの単純な文字列チェックを実行し、それ以上何も実行しないと想像すると、すべて正常に動作します。

しかしisMobileDevice()、何かへの HTTP リクエストを実行する関数が必要です。これは、応答が完了したときに呼び出されるコールバック関数を持つことを意味します。これを行うことは可能で、ビルダー パターンをそのまま維持することはできますか? 次のようなことができると思います:

redirectWhen.isMobileDevice(function() {
  urlMatches("...").thenGoTo("...");
});

しかし、それは私が望む以上にスクリプトを複雑にしています。これらのスクリプトを管理する担当者は基本的な JavaScript を知っていますが、コールバックのネストを開始する必要がある場合、すぐに混乱することになると思います。

ここでは不可能なことを達成しようとしていると思いますが、それを確認できるほど十分なJSを知りません!

4

3 に答える 3

1

それは完全に可能です。ビルダーは各ステップで中間オブジェクトを返し、最後のステップで最終的にピースをまとめて最終関数を呼び出します。

function redirectWhen() {
    var building = {};  // saved state goes here

    // actually implement redirection
    function build() {
        // expects building = { source: "...", target: "...", mobile: optionalBoolean}            
        if (building.mobile) {
           checkMobile();
        } else {
           finishBuild();
        }
    }

    function checkMobile() {
        // check if actually mobile by making an HTTP request
        // in the success callback, calls finishBuild - fails otherwise
        // ..
    }

    function finishBuild() {
        // accessible only if mobile not requested, or if requested and mobile check passed
        // ..
    }

    // prepare the second step
    var urlMatches = function(url) {
        building.source = url;
        return { thenGoTo: function(target) { building.target = target; build(); } }
    }

    // return the next steps
    return { 
       isMobileDevice: function() { builder.mobile = true; return urlMatches; },
       urlMatches: urlMatches
    }
}

モバイル テストをサポートするには、ビルドを 2 つの部分 (チェックとコールバック) に分割します。しかし、これはビルド機能がどこかにあることさえ知らないユーザーにはわかりません。

于 2013-01-23T10:57:34.643 に答える
1

非同期で動作させるためだけに、エレガントな構築パターンをあきらめる必要はありません。ノードのリンク リストを作成し、各ノードが成功したときに次のノードを呼び出すことができます。

および複数の実装を使用してフィドルを設定しました。いくつかのメモ:ChainChainNode

  • それぞれに、独自の処理が完了したときに呼び出す必要がChainNodeあるexecute()メソッドと があります。たとえば、URL パターン マッチャーは、URL がパターンに一致する場合にのみ次のノードを呼び出します。nextNodenext()
  • は、コールバックから何らかの非同期呼び出し (AJAX など) へのIsMobileNode呼び出しによって実装できます。next()フィドルでは、単純なsetTimeout概念が示されています。
  • は、実行の開始場所を示す と、新しいノードを追加する をChain保持します。この方法により、チェーンが完全に保持されます。headtailchain(nextNode)
  • urlMatches(urlPattern)およびisMobileDevice()メソッドは、単純にノードを作成し、それをチェーンに追加します。
  • このthenGoTo()メソッドは、最終ノードをチェーンしてリダイレクトを開始します。次に、 から始まるチェーンを実行しheadます。
于 2013-01-23T12:09:06.250 に答える
0

私の質問に対する Dan Lee のコメントも、Q ライブラリー ( https://github.com/kriskowal/q )にたどり着くのに役立ちました。他の答えほど単純ではありませんが、それは確かに私が望んでいたことに役立ちます。

于 2013-01-23T14:56:12.507 に答える