如何判断Ajax请求与fetch请求均已完成?
问题分析与修复方案
你的代码存在两个关键问题,导致无法准确等待两个任务全部完成:
1. runPerformanceTest未返回Promise
runPerformanceTest内部执行了fetch请求,但没有把整个Promise链返回出去,导致performanceTestPromise实际是undefined。Promise.all遇到非Promise值会直接判定为已完成状态,所以只要Ajax任务结束,就会触发then回调,完全忽略性能测试的完成状态。
2. Ajax的Promise封装未正确触发状态变更
你手动封装的ajaxCallPromise中,success和error回调没有调用resolve()或reject(),这个Promise永远不会进入完成状态——虽然你提到Ajax完成后会标记状态,但规范写法必须调用这两个方法,或者直接使用jQuery.ajax自带的Promise,更简洁可靠。
修改后的完整代码
先修复runPerformanceTest,让它返回Promise:
function runPerformanceTest(url) { // 返回整个fetch的Promise链,让外部能跟踪状态 return fetch(url) .then((response) => response.json()) .then((json) => { const test = json.test?.metrics; if (test) { showcontent() } const test2 = json.test2; if (test2) { showcontent2() } }) .catch((error) => { console.error("Error fetching data:", error); // 抛出错误,让Promise.all能捕获到失败状态 throw error; }); }
再修复runAutomaticTest的Ajax部分:
直接使用jQuery.ajax自带的Promise,无需手动封装:
function runAutomaticTest() { if (isRunningTest) { return; } isRunningTest = true; // 现在performanceTestPromise是有效的Promise const performanceTestPromise = runPerformanceTest(urlToTest); // 直接使用jQuery.ajax返回的Promise const ajaxCallPromise = jQuery.ajax({ type: "POST", url: ajax_site_url, dataType: "json", data: { action: "automatic-test", } }) .done((response) => { // 这里可以添加Ajax成功后的业务逻辑 }) .fail((xhr, status, error) => { console.error("Ajax请求失败:", error); }); // 等待两个任务全部完成 Promise.all([performanceTestPromise, ajaxCallPromise]) .then(() => { console.log("两个测试任务全部完成!"); isRunningTest = false; }) .catch((error) => { console.error("至少一个测试任务失败:", error); isRunningTest = false; }); }
核心说明
runPerformanceTest必须返回Promise,这样Promise.all才能跟踪它的完成状态。- jQuery的Ajax从1.5版本开始就返回标准兼容的Promise对象,直接使用即可,避免手动封装的错误。
Promise.all会严格等待所有传入的Promise完成(或任意一个失败)才触发回调,确保你能准确知晓两个任务的整体完成状态。
内容的提问来源于stack exchange,提问作者eligolf
相关产品推荐
相关产品推荐

