繁体   English   中英

Ajax并行发布:为每个请求定义超时并仅获得成功

[英]Ajax parallel post: Define timeout for each request and get only suceeded

我的问题是,当我们使用jquery延迟接口时,有一种方法可以为每个并行ajax帖子定义超时。 例如

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
            };
        }

每个并行发布的超时定义为1000和2000。我的目标是获得在定义的超时中成功的响应。 因此,当第一个请求超时而第二个请求没有超时时,则仅返回第二个响应。

如果至少有一个超时,则通过jquery延迟接口调用失败回调。

有没有一种方法可以定义这种行为,或者可能是另一个提供问题解决方案的接口

这就是我要怎么做...

首先,对于一般原理,请阅读此答案

现在,以可链接的.jqXhrReflect()方法为幌子实现reflect() ,该方法返回:

  • 成功:jQuery.ajax成功将args捆绑到一个对象中,
  • 错误:承诺与jQuery.ajax错误args捆绑在一起。
(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);

注意:自定义jQuery Promise方法不直观

然后按如下所示更改parallelPost()

  • 接受现成的ajax选项,
  • 不接受successHandler,errorHandelr,completeHandler args,
  • 过滤ajax响应以分离出结果和错误。
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';
            })
        };
    });
},

然后更改.createAjaxCall()以实际执行ajax调用,并使用上面定义的.jqXhrReflect()方法转换响应:

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.
}

现在您可以打电话

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
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM