译 asp.net ajax underthehood secret

原文地址:http://www.codeproject.com/KB/ajax/aspnetajaxtips.aspx

1.批量调用不一定经常快

Batch Calls Are Not Always Faster

2.坏的调用会让好的调用超时

Bad Calls Make Good Calls Time Out
解决方法:重写客户端方法,Sys.Net.WebRequestProxy.invoke
Sys.Net.WebServiceProxy.retryOnFailure =
    function(result, userContext, methodName, retryParams, onFailure)
{
    if( result.get_timedOut() )
    {
        if( typeof retryParams != "undefined" )
        {
            debug.trace("Retry: " + methodName);
            Sys.Net.WebServiceProxy.original_invoke.apply(this, retryParams );
        }
        else
        {
            if( onFailure ) onFailure(result, userContext, methodName);
        }
    }
    else
    {
        if( onFailure ) onFailure(result, userContext, methodName);
    }
}

Sys.Net.WebServiceProxy.original_invoke = Sys.Net.WebServiceProxy.invoke;
Sys.Net.WebServiceProxy.invoke =
    function Sys$Net$WebServiceProxy$invoke(servicePath, methodName, useGet,
        params, onSuccess, onFailure, userContext, timeout)
{  
    var retryParams = [ servicePath, methodName, useGet, params,
        onSuccess, onFailure, userContext, timeout ];
   
    // Call original invoke but with a new onFailure

    // handler which does the auto retry

    var newOnFailure = Function.createDelegate( this,
        function(result, userContext, methodName)
        {
            Sys.Net.WebServiceProxy.retryOnFailure(result, userContext,
                methodName, retryParams, onFailure);
        } );
       
    Sys.Net.WebServiceProxy.original_invoke(servicePath, methodName, useGet,
        params, onSuccess, newOnFailure, userContext, timeout);
}

3.浏览器在同一时间只允许两个调用,不要期望其他的指令
Browsers Allow Two Calls at a Time and Don't Expect any Order
浏览其不会回复当有2个以上的请求在队列中时。
Browsers Do Not Respond when More Than Two Calls Are in Queue
解决方法:建立一个队列,将所有请求封装入一个QueueCall中,
var GlobalCallQueue = {
    _callQueue : [],    // Maintains the list of webmethods to call

    _callInProgress : 0,    // Number of calls currently in progress by browser

    _maxConcurrentCall : 2, // Max number of calls to execute at a time

    _delayBetweenCalls : 50, // Delay between execution of calls

    call : function(servicePath, methodName, useGet,
        params, onSuccess, onFailure, userContext, timeout)
    {
        var queuedCall = new QueuedCall(servicePath, methodName, useGet,
            params, onSuccess, onFailure, userContext, timeout);

        Array.add(GlobalCallQueue._callQueue,queuedCall);
        GlobalCallQueue.run();
    },
    run : function()
    {
        /// Execute a call from the call queue

       
        if( 0 == GlobalCallQueue._callQueue.length ) return;
        if( GlobalCallQueue._callInProgress <
            GlobalCallQueue._maxConcurrentCall )
        {
            GlobalCallQueue._callInProgress ++;
            // Get the first call queued

            var queuedCall = GlobalCallQueue._callQueue[0];
            Array.removeAt( GlobalCallQueue._callQueue, 0 );
           
            // Call the web method

            queuedCall.execute();
        }
        else
        {
            // cannot run another call. Maximum concurrent

            // webservice method call in progress

        }           
    },
    callComplete : function()
    {
        GlobalCallQueue._callInProgress --;
        GlobalCallQueue.run();
    }
};

QueuedCall = function( servicePath, methodName, useGet, params,
    onSuccess, onFailure, userContext, timeout )
{
    this._servicePath = servicePath;
    this._methodName = methodName;
    this._useGet = useGet;
    this._params = params;
   
    this._onSuccess = onSuccess;
    this._onFailure = onFailure;
    this._userContext = userContext;
    this._timeout = timeout;
}

QueuedCall.prototype =
{
    execute : function()
    {
        Sys.Net.WebServiceProxy.original_invoke(
            this._servicePath, this._methodName, this._useGet, this._params, 
            Function.createDelegate(this, this.onSuccess), // Handle call complete

            Function.createDelegate(this, this.onFailure), // Handle call complete

            this._userContext, this._timeout );
    },
    onSuccess : function(result, userContext, methodName)
    {
        this._onSuccess(result, userContext, methodName);
        GlobalCallQueue.callComplete();           
    },       
    onFailure : function(result, userContext, methodName)
    {
        this._onFailure(result, userContext, methodName);
        GlobalCallQueue.callComplete();           
    }       
};


4.在浏览器中缓存WEB SERVICE的响应。明显的节省带宽
Caching Web Service Response on the Browser and Saving Bandwidth Significantly
解决方法:
(1)修改HTTP Response headers ,在方法中添加[ScriptMethod(UseHttpGet=true)] attributes
(2)HttpHeader 中_maxage不能直接修改,用反射方法。
(3)要在客户端使用放射方法必须在WEB.CONFIG中申明<trust Level="full">
[WebMethod][ScriptMethod(UseHttpGet=true)]
public string CachedGet2()
{
    TimeSpan cacheDuration = TimeSpan.FromMinutes(1);

    FieldInfo maxAge = Context.Response.Cache.GetType().GetField("_maxAge",
        BindingFlags.Instance|BindingFlags.NonPublic);
    maxAge.SetValue(Context.Response.Cache, cacheDuration);

    Context.Response.Cache.SetCacheability(HttpCacheability.Public);
    Context.Response.Cache.SetExpires(DateTime.Now.Add(cacheDuration));
    Context.Response.Cache.AppendCacheExtension(
            "must-revalidate, proxy-revalidate");

    return DateTime.Now.ToString();
}

5.什么时候this不是真正的this.
我们要知道不论何时javascript触发,this指代引发此事件的html元素。
we know that whenever JavaScript events are raised, this refers to the HTML element that produced the event.

6.http get方法比http post方法要快,但是asp.net ajax 中默认的是 post方法。

原文地址:https://www.cnblogs.com/hsj/p/1187669.html