2

writeMessageという関数があります。writeMessageは、ローカライズされたコンテンツを取得するためにajaxリクエストを呼び出します。また、コンテンツがajaxリクエストから返されると、「n」秒後にメッセージがフェードアウトします。したがって、すべてが機能し、いくつかの呼び出しでテストしましたが、JavaScriptのクロージャーステートメントを処理するときに変数のスコープを完全に理解していないため、非常に複雑だと感じています。私がここであまりにも多くのフープを飛び越えて以下を達成することができないかどうか誰かにアドバイスできますか?

関数getTextResourceはパラメーター(文字列、文字列、オブジェクト、関数)を取ります

  • 'function'パラメーターは、ajaxリクエストが完了すると呼び出されるコールバックです。
  • 'object'パラメータは、メッセージの書き込み方法と書き込み場所に関するすべての詳細を含む引数オブジェクトです。
  • 'string'および'string'パラメーターがajaxリクエストに渡されています。

getTextResource内で、元のデフォルトテキストとコールバック関数とともに'object'パラメーターをコンテキストとして渡すajaxメソッドを呼び出しています。ajaxリクエストが完了すると、コンテキストを介して、次の結果を渡すコールバック関数を呼び出します。引数とともにサービス呼び出し。

コンテキストを渡し続ける必要がありますか、それとも関数が再度呼び出された場合にgetTextResoruceに渡されるすべてのものに別の値が割り当てられないようにする必要がありますか?

function writeMessage(args) {
    var d = $('<div></div>');

    getTextResource(args.resourceId, args.message, { args: args, messageElement: d },
        function (text, context) {
            var args = context.args;
            var d = context.messageElement;

            d.empty();
            d.append(text);

            args.element.append(d);

            if (args.fadeTimeOut > 0)
                setTimeout(function () {
                    d.fadeOut('slow', function () {
                        $(this).remove();
                    });
                }, args.fadeTimeOut);
        }
    );
}

var getTextResource = function (resourceId, defaultText, context, cb) {
    resourceId = resourceId + '';
    defaultText = defaultText + '';

    if (resourceId == '') resourceId = defaultText;
    if (defaultText == '') defaultText = resourceId;

    try{
        var request = $.ajax({
            type: 'GET',
            url: 'http://localhost/EaiCCM/api/' + BusinessScope.Version + '/' + BusinessScope.CampaignSegment + '/TextResource',//?' + qs,
            data:  {ResourceId: resourceId, DefaultText: defaultText},
            cache: false,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            context: { defaultText: defaultText, context: context, cb: cb }
        });

        request.done(function (result) {
            var txt = this.defaultText;
            try {
                if ($.isPlainObject(result))
                    txt = result.Detail;
            }
            catch (e) {
            }
            finally {
                if (typeof this.cb == 'function')
                    this.cb(txt, this.context);
            }
        });

        request.fail(function (jqXHR, textStatus, context) {
            if (typeof this.cb == 'function')
                this.cb(this.defaultText, this.context);
        });
    }
    catch (e) {
        if (typeof cb == 'function')
            cb(defaultText, context);
    }
};
4

1 に答える 1

0

contextいいえ、のスコープでコールバックを構築している場合は、コールバックのオブジェクトは必要ありませんwriteMessage。(スコープは、関数の各呼び出しに対してローカルです。)

これ:

    function (text, context) {
        var args = context.args;
        var d = context.messageElement;

同じように簡単にできます:

    function (text) {

そしてrequest.done読むことができます:

    request.done(function (result) {
        var txt = defaultText;
        try {
            if ($.isPlainObject(result))
                txt = result.Detail;
        }
        catch (e) {
        }
        finally {
            if (typeof cb == 'function')
                cb(txt);
        }
    });

引数のスコープは、引数の対象となる関数の各呼び出しになります。var変数は、ステートメントのfunction上の最初の呼び出しにスコープされます。スコープは、それを閉じる中括弧までのみ存続しますvarfunction

したがって、このコードでは:

function writeMessage(args) {
  var d = $('<div></div>');
  var rid = args.resourceId;

  var cb = function (text) {
    var exampleVar = text.toUpper();
    d.textContent = exampleVar + rid;
  }

  getTextResource(rid+'-san', 'foo', cb)
  getTextResource(rid+'-chan', 'bar', cb)
}

function getTextResource(resourceId,defaultText,cb) {
  // for simplicity's sake let's just simulate a default scenario

  // Note that the `resourceId` passed to `getTextResource`
    // is in no way passed to the callback here

  cb(defaultText);
}
  • args、、ridおよびdは、の各呼び出しに対してローカルですwriteMessage
  • textexampleVarは、コールバックの各呼び出しに対してローカルcbです。
  • resourceIddefaultText各呼び出しに対してローカルですgetTextResource
  • cbはで作成するコールバックwriteMessageであり、で渡すコールバックgetTextResourceです。それらは同じ名前ですが、スコープが異なるということは、2つの異なる変数として効果的に扱われることを意味します。(これが紛らわしい場合は、以下の例えを参照してください。)
  • getTextResourceでコールバックを呼び出すと、のコールバックを呼び出すときと'bar'同じdように変更されます。これは、コールバック'foo'で使用されるのは、それが構築されたd場所に対してローカルであるためです。writeMessage
  • ただし、 ofが設定されexampleVarている値は、コールバックに対してローカルであるため、呼び出しごとに異なります。textContentd
  • の値は、のスコープに追加されるため、追加のまたはで終了しexampleVarませ。これは、のスコープにはまったく表示されません(変数が呼び出され、とにかく)。'-san''-chan'resourceIdgetTextResourcewriteMessageridresourceId

異なるスコープ内の同じ名前の変数の例え

変数名は、「ボブ」がボブズバーガーズではボブとはたらくブーブとは異なる人物を意味するように、さまざまなコンテキストでさまざまな値を参照します。ただし、あるコンテキストでの「ボブ」は、元のコンテキストでは「ボブ」とも呼ばれていたものを指す可能性があります。たとえば、スターリングが「ボブ」と呼ばれ、「ボブズバーガーズ」で働くアーチャーシーズン4の最初のエピソードのように"(両方のキャラクターに声を提供するH.ジョンベンジャミンへの参照として)。それは偶然の一致であり、「本物の」ボブズバーガーズ「ボブ」はアーチャーの世界のどこかに存在していると言えますが、彼が同じ「ボブ」であるかどうかは関係ありません。次への射手

于 2013-03-02T17:10:46.900 に答える