Ajax parallel post: 为每个请求定义超时,只获取成功
Ajax parallel post: Define timeout for each request and get only suceeded
我的问题是,当我们使用 jquery 延迟接口时,有一种方法可以为每个并行 ajax post 定义超时。例如
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
};
}
每个并行 post 的超时定义为 1000 和 2000。我的目标是获得在定义的超时内成功的响应。因此,当第一个请求超时而第二个请求没有超时时,return 只有第二个响应。
通过 jquery 延迟接口,如果至少有一个超时失败回调被调用。
是否有一种方法可以定义此类行为,或者可能是提供问题解决方案的另一个接口
以下是我的操作方式...
首先,对于一般原则,阅读。
现在,以可链接 .jqXhrReflect()
方法的形式实施 reflect()
,其中 returns:
- 成功时:jQuery.ajax 将成功参数捆绑到单个对象中,
- 发生错误:通过将 jQuery.ajax 错误参数捆绑到单个对象中解决了承诺。
(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 参数,
- 过滤 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
});
我的问题是,当我们使用 jquery 延迟接口时,有一种方法可以为每个并行 ajax post 定义超时。例如
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
};
}
每个并行 post 的超时定义为 1000 和 2000。我的目标是获得在定义的超时内成功的响应。因此,当第一个请求超时而第二个请求没有超时时,return 只有第二个响应。
通过 jquery 延迟接口,如果至少有一个超时失败回调被调用。
是否有一种方法可以定义此类行为,或者可能是提供问题解决方案的另一个接口
以下是我的操作方式...
首先,对于一般原则,阅读
现在,以可链接 .jqXhrReflect()
方法的形式实施 reflect()
,其中 returns:
- 成功时:jQuery.ajax 将成功参数捆绑到单个对象中,
- 发生错误:通过将 jQuery.ajax 错误参数捆绑到单个对象中解决了承诺。
(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 参数,
- 过滤 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
});