首页 > 解决方案 > Promise.all 数组 $.ajax() 调用的进度条

问题描述

最终更新 25/06/20:好的,所以这不起作用有多种原因。

  1. $.ajax() 使用起来很痛苦,因为它并没有真正返回正确的承诺。所以任何依赖它的实现都不起作用。这部分的解决方案是改用 AXIOS 进行调用。
  2. 在这个过程中,我实际上打了很多电话。我最初认为我进行的第一组调用很小,并且在栏填满之前并没有导致很多加载时间。我预计第二组调用需要很长时间,因此只对进度条进行编码以考虑到这一点。在分析了网络流量之后,事实证明这是完全相反的。所以我的解决方案实际上是让进度条填满两次:一次用于“准备调用”(实际上需要最长的时间),然后在实际请求调用的响应中再次填满。

感谢所有提供建议的人,一旦我弄清楚我哪里出错了,它就很有帮助!


2020 年 6 月 25 日更新:这是一个指向 Gist 的链接,其中包含整个函数,因为它太大,无法在此处发布:Gist 中的函数。第 215 行是我将 $.ajax() 调用添加到 matchPromises 的地方。第 274 行是我调用 Promise.allSettled(matchPromises) 的地方


我在尝试为此获得工作进度条时遇到很多问题。我不会发布我的实际代码,因为它太长了,但我会发布它的要点。

ajax 调用是这样的:

$.ajax({
    "url": myUrl,
    "method": "POST",
    "success": (data) => {
        doStuff
        // POINT A
     },
     "error": (data) => {
         doStuff
     }
})

我将它们推入一个名为的数组中matchPromises,然后调用Promise.allSettled(matchPromises)它。这一切都很好。

我遇到的问题是尝试更新进度条以指示完成了多少承诺。我在函数顶部有以下内容,我正在做其他所有事情:

let currentProgress = 0;
let maxProgress = 0;

function displayProgress() {
    currentProgress++;
    let calculatedWidth = (currentProgress / maxProgress) * 100;
    $('#progressBar').width(`${calculatedWidth}%`);
    $('#progressBar').attr('aria-valuenow', currentProgress);
}

我在调用之前Promise.allSettled(matchPromises)使用matchPromises.length.

我曾尝试将$.ajax 调用displayProgress()success一部分放入 - 但问题是每次调用时 maxProgress 将始终保持为 0。

我已经尝试了很多不同的方法来$.ajax通过将它包装在 a 中new Promise并添加来保证它.then()- 而且这正确读取maxProgress- 但无论我尝试过哪种方法,它只会在Promise.allSettled完成后在一个巨大的块中调用它。

我已经在这几个小时了,并尝试了很多不同的方法。真的希望有人可以帮助我解决这个问题,因为我已经走到了尽头。

标签: javascriptjqueryajaxpromiseprogress-bar

解决方案


由于缺少一些代码可以将其应用于您的情况,因此无论如何我都试图草拟一个有用的解决方案。

我希望这可以解决您的问题,或者至少能给您一些启发。

const getLongRunningPromise = (millis, value) => {
    return new Promise((resolve) => {
        setTimeout(() => resolve(value), millis)
    });
};

const promises = [getLongRunningPromise(5000, 'a'), getLongRunningPromise(1000, 'b')];

let doneCount = 0;
const overallCount = promises.length;

const handleProgress = (result) => {
    doneCount++;
    const percentageDone = doneCount/overallCount*100;
    console.log(`${percentageDone}% Done`);
    return result;
};

Promise.all(promises.map(p => p.then(handleProgress))).then((results) => console.log('results', results));


推荐阅读