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() 聚合会自动导致 statusTextjqXHR 被丢弃,但是将这些丢弃显式显示并没有真正的危害,除非你需要执着于毫秒

从错误处理程序返回 $.Deferred().reject(new Error(textStatus || errorThrown)).promise() 应该在 jQuery 的所有版本中提供相同的行为,从而导致在错误路径上传递错误对象。 (虽然记录的错误消息会有所不同)请务必对此进行测试。