2016-06-06 2 views
0

Meine Frage ist, gibt es eine Möglichkeit, Timeout für jeden parallelen Ajax-Post zu definieren, wenn wir jquery Schnittstelle verwendet haben. Z.B.Ajax parallel post: Definieren Timeout für jede Anfrage und erhalten nur

parallelPost: function(toUrl1, toUrl2, theData1, theData2, contentType, dataType, successHandler, errorHandelr, completeHandler) { 

$.when($.ajax(this.createAjaxCall(toUrl1, theData1, true, headers, 'POST', contentType, dataType,1000)), 
       $.ajax(this.createAjaxCall(toUrl2, theData2, true, headers, 'POST', contentType, dataType,2000))).done(function(res1, res2) { 
       successHandler(res1, res2); 
      }, errorHandelr, completeHandler); 
     }, 
     createAjaxCall: function(toUrl, theData, isAsync, headers, verb, contentType, dataType, timeout, successHandler, errorHandelr, completeHandler) { 
      return { 
       url: toUrl, 
       cache: false, 
       type: verb, 
       data: theData, 
       dataType: dataType, 
       timeout: timeout || 0, 
       async: isAsync, 
       headers: headers, 
       contentType: contentType ? contentType : 'application/x-www-form-urlencoded', 
       success: successHandler, 
       error: errorHandelr, 
       complete: completeHandler 
      }; 
     } 

Die Timeouts für jeden parallelen Beiträge wurden 1000 und 2000. Mein Ziel definiert diese Antworten zu erhalten, die in definierten Timeouts gelungen waren. Wenn also die erste Anfrage zeitlich geortet wurde und die zweite nicht, geben Sie nur die zweite Antwort zurück.

Über jQuery Schnittstelle deaktiviert, wenn mindestens eine zeit-geoutet Fail Callback aufgerufen wird.

Gibt es eine Möglichkeit ein solches Verhalten zu definieren, oder kann eine andere Schnittstelle sein, die Lösung bieten

Antwort

1

hier auszustellen ist, wie ich dies tun würde ...

Zuerst für das allgemeine Prinzip, lesen this answer.

Nun implementieren reflect() in der Gestalt einer verkettbar .jqXhrReflect() Methode, die zurückgibt:

  • auf Erfolg: jQuery.ajax Erfolg args zu einem einzigen Objekt gebündelt,
  • auf Fehler: ein Versprechen gelöst mit jQuery.ajax Fehlerargumente in einem einzigen Objekt gebündelt.
(function($) { 
    if(!$.$P) { 
     $.$P = function() { 
      return (this instanceof $.$P) ? this : (new $.$P()); 
     }; 
    } 
    if(!$.$P.prototype.jqXhrReflect) { 
     $.$P.prototype.jqXhrReflect = function() { 
      /* A promise method that "reflects" a jqXHR response. 
      * Delivers, on the success path, an object that bundles : 
      * - jqXHR success arguments (data, textStatus, xhr) or 
      * - jqXHR error arguments (xhr, textStatus, errorThrown). 
      */ 
      return this.then(
       function(data, textStatus, xhr) { return { 'data':data, 'textStatus':textStatus, 'xhr':xhr }; }, 
       function(xhr, textStatus, errorThrown) { return $.when({ 'xhr':xhr, 'textStatus':textStatus, 'errorThrown':errorThrown }); } 
      ); 
     }; 
    } 
})(jQuery); 

Hinweis: Benutzerdefinierte jQuery Versprechen Methoden sind nicht intuitiv

Dann parallelPost() wie folgt ändern:

  • fertig geformte Ajax-Optionen zu akzeptieren,
  • nicht um Erfolg zu akzeptierenHandler, errorHandelr, completeHandler args,
  • um die Ajax-Antworten zu filtern, um Ergebnisse und Fehler zu trennen.
parallelPost: function(ajaxOptions1, ajaxOptions2) { 
    return $.when(
     this.ajaxCall(ajaxOptions1), 
     this.ajaxCall(ajaxOptions2) 
    ).then(function() { 
     var args = Array.prototype.slice.call(arguments); 
     // here, apply various filters 
     return { 
      all: args, 
      results: args.filter(function(obj) { 
       return obj.data !== undefined; 
      }), 
      allErrors: args.filter(function(obj) { 
       return obj.errorThrown !== undefined; 
      }), 
      timeouts: args.filter(function(obj) { 
       return obj.errorThrown && obj.textStatus === 'timeout'; 
      }), 
      otherErrors: args.filter(function(obj) { 
       return obj.errorThrown && obj.textStatus !== 'timeout'; 
      }) 
     }; 
    }); 
}, 

Dann .createAjaxCall() tatsächlich ändern, um den Ajax-Aufruf durchführt und die Antwort mit der .jqXhrReflect() Methode transmogrify oben definiert:

ajaxCall: function(ajaxOptions) { 
    var ajaxDefaults = { 
     cache: false, 
     type: 'POST', 
     dataType: 'JSON', // or whatever 
     async: false, 
     contentType: 'application/x-www-form-urlencoded' 
    }; 
    return $.ajax($.extend(ajaxDefaults, ajaxOptions)) // $.extend does the necessary magic of merging ajaxDefaults and ajaxOptions. 
     .promise($.$P()) // make the .jqXhrReflect() method available. 
     .jqXhrReflect(); // call the .jqXhrReflect() method. 
} 

Jetzt können Sie anrufen,

myObj.parallelPost(
    { url: 'path/to/resource1', timeout: 1000 }, 
    { url: 'path/to/resource2', timeout: 2000 } 
).then(function(outcomes) { 
    // this success callback is guaranteed to fire and will make the following available : 
    // array outcomes.all 
    // array outcomes.results 
    // array outcomes.allErrors 
    // array outcomes.timeouts 
    // array outcomes.otherErrors 
});