jQuery .当没有按预期使用 rest 运算符时
jQuery .when not working as expected with rest operator
所以在我们的代码库中,我们仅将 jquery 用于代码库的 ajax 部分,但我们希望包装所有调用,以便最终摆脱 jquery 那么我们只需要更改实现即可。这是包装器的定义。
export const getAll = (...ajaxCalls) => {
// return $.when($.ajax(ajaxCalls));
return $.when(ajaxCalls.map(call => $.ajax(call)));
}
这里是我们调用它的地方。
getAll(`/response/${customerId}`, `/response/${methods}`).done((response1, response2) => {
console.log("getAll1",response1);
console.log("getAll2",response2);
})
但是响应看起来像这样:
我的理解是什么时候 response1 应该包含 response1 的 responseBody,response2 应该包含 response2 的 responseBody,但事实似乎并非如此。我错过了什么?
您似乎正在记录 jqHXR 对象,这可能是 jQuery.ajax()
和 jQuery.when()
交互以交付结果的奇怪方式的结果 see last but one example here。
考虑到稍后会清除jQuery,我冒昧地建议您在此阶段需要对所有调用进行标准化。这相当简单,只需使用 .then()
而不是 .done()
并期望结果以数组形式传递:
getAll(`/response/${customerId}`, `/response/${methods}`)
.then(results => {
console.log("getAll0", results[0]);
console.log("getAll1", results[1]);
});
然后您需要跳过 getAll()
中的几个环节,以便标准化 jQuery.ajax()
和 jQuery.when()
行为的各个方面:
- 将 jQuery.when() 的传递结果标准化为单独的参数而不是数组。
- 将 jQuery.ajax() 的(数据、statusText、jqXHR)传递标准化到它的成功路径。
- 标准化 jQuery.ajax() 将 (jqXHR, statusText, errorThrown) 传送到它的错误路径。
- 在 jQuery 的不同版本中标准化
jQuery.ajax()
的错误处理程序的行为。
export const getAll = (...ajaxCalls) => {
function makeAjaxCallAndStandardizeResponse(call) {
return $.ajax(call)
.then(
// success handler: standardize success params
(data, statusText, jqXHR) => data, // discard statusText and jqXHR
// error handler: standardize error params and ensure the error does not remain "caught".
(jqXHR, textStatus, errorThrown) => $.Deferred().reject(new Error(textStatus || errorThrown)).promise(); // discard jqXHR, and deliver Error object on the error path.
);
}
// Aggregate with Promise.all() instead of jQuery.when() to cause a javascript Promise to be returned and results to be delivered as Array.
return Promise.all(ajaxCalls.map(makeAjaxCallAndStandardizeResponse));
}
成功处理程序可能是不必要的,因为 Promise.all()
聚合会自动导致 statusText
和 jqXHR
被丢弃,但是将这些丢弃显式显示并没有真正的危害,除非你需要执着于毫秒
从错误处理程序返回 $.Deferred().reject(new Error(textStatus || errorThrown)).promise()
应该在 jQuery 的所有版本中提供相同的行为,从而导致在错误路径上传递错误对象。 (虽然记录的错误消息会有所不同)请务必对此进行测试。
所以在我们的代码库中,我们仅将 jquery 用于代码库的 ajax 部分,但我们希望包装所有调用,以便最终摆脱 jquery 那么我们只需要更改实现即可。这是包装器的定义。
export const getAll = (...ajaxCalls) => {
// return $.when($.ajax(ajaxCalls));
return $.when(ajaxCalls.map(call => $.ajax(call)));
}
这里是我们调用它的地方。
getAll(`/response/${customerId}`, `/response/${methods}`).done((response1, response2) => {
console.log("getAll1",response1);
console.log("getAll2",response2);
})
但是响应看起来像这样:
我的理解是什么时候 response1 应该包含 response1 的 responseBody,response2 应该包含 response2 的 responseBody,但事实似乎并非如此。我错过了什么?
您似乎正在记录 jqHXR 对象,这可能是 jQuery.ajax()
和 jQuery.when()
交互以交付结果的奇怪方式的结果 see last but one example here。
考虑到稍后会清除jQuery,我冒昧地建议您在此阶段需要对所有调用进行标准化。这相当简单,只需使用 .then()
而不是 .done()
并期望结果以数组形式传递:
getAll(`/response/${customerId}`, `/response/${methods}`)
.then(results => {
console.log("getAll0", results[0]);
console.log("getAll1", results[1]);
});
然后您需要跳过 getAll()
中的几个环节,以便标准化 jQuery.ajax()
和 jQuery.when()
行为的各个方面:
- 将 jQuery.when() 的传递结果标准化为单独的参数而不是数组。
- 将 jQuery.ajax() 的(数据、statusText、jqXHR)传递标准化到它的成功路径。
- 标准化 jQuery.ajax() 将 (jqXHR, statusText, errorThrown) 传送到它的错误路径。
- 在 jQuery 的不同版本中标准化
jQuery.ajax()
的错误处理程序的行为。
export const getAll = (...ajaxCalls) => {
function makeAjaxCallAndStandardizeResponse(call) {
return $.ajax(call)
.then(
// success handler: standardize success params
(data, statusText, jqXHR) => data, // discard statusText and jqXHR
// error handler: standardize error params and ensure the error does not remain "caught".
(jqXHR, textStatus, errorThrown) => $.Deferred().reject(new Error(textStatus || errorThrown)).promise(); // discard jqXHR, and deliver Error object on the error path.
);
}
// Aggregate with Promise.all() instead of jQuery.when() to cause a javascript Promise to be returned and results to be delivered as Array.
return Promise.all(ajaxCalls.map(makeAjaxCallAndStandardizeResponse));
}
成功处理程序可能是不必要的,因为 Promise.all()
聚合会自动导致 statusText
和 jqXHR
被丢弃,但是将这些丢弃显式显示并没有真正的危害,除非你需要执着于毫秒
从错误处理程序返回 $.Deferred().reject(new Error(textStatus || errorThrown)).promise()
应该在 jQuery 的所有版本中提供相同的行为,从而导致在错误路径上传递错误对象。 (虽然记录的错误消息会有所不同)请务必对此进行测试。