当所有 xmlHttpRequests 完成时执行函数

Execute A Function When All xmlHttpRequests Are Complete

简介

我有一个从 API 获取数据的网站。因此,一旦网站打开,它就会发出一些 post 并向服务器发出请求。让我们假设它在页面加载后立即发出 5 个不同的 xmlHttpRequests,但我们无法确切知道每次调用从开始到结束所花费的时间。

例如

对一个端点的调用需要 2 秒才能完成,而另一个端点需要 1 秒才能完成。所以这意味着在 2 秒后,两个调用都被认为是 finished.

待办事项

我想在所有 xmlHttpRequests complete 之后执行一个函数,因为我正在使用 window.performance.getEntries() 获取网页发起的所有请求并将其发送到我的服务器,因为我正在做一个网络分析项目,我需要访问每个网络请求所花费的时间并将数据转换为图表。

额外问题或提示

是否有任何事件可以附加到 window,如下所示,以侦听所有网络调用并在所有完成后执行我的代码。

      window.addEventListener("load", function (event) {
       //execute some code here
      }

在加载事件中,我无法使用 performance.getEntries() 捕获所有请求,因为加载在 ajax 调用完成之前触发.

如上图我问。 JavaScript 中是否有任何技巧或任何事件或任何东西,我们可以通过它等到所有 XMLHTTPREQUESTS 完成然后执行一些代码。

我建议您将请求包装在 promise 中,然后像这样使用 Promise.all(...)

const makeRequest = () => {
    return new Promise((resolve, reject) => {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                resolve(xhttp.responseText); // On success, resolve the promise
            } else {
                reject(); // On failure, reject it
            }
        };
        xhttp.open("GET", "filename", true); // Needs to be set to your needs. This is just an example
        xhttp.send();
    });
}

// This waits until all promises are resolved
const [result1, result2] = await Promise.all(makeRequest(), makeRequest());

// do stuff here with your results
console.log(result1);
console.log(result2);

PS:基本 Ajax 示例来自 here,但只需将其替换为您的并创建参数或类似参数以发出您实际需要的请求

您可以使用像 Axios 这样的库来处理 Ajax 请求,默认情况下已经 returns Promise。在这里查看:https://github.com/axios/axios

工作解决方案

我们可以使用以下代码跟踪浏览器 AJAX 调用:

  const ajaxCallStatus = () => {
   window.ajaxCalls = 0; // initial ajax calls
   window.ajaxEndpoints = []; // keeping track of all ajax call urls (endpoints) 
   const origOpen = XMLHttpRequest.prototype.open;
   XMLHttpRequest.prototype.open = function() {
   window.ajaxCalls++;
   this.addEventListener('load', (event) => {
    if (!window.ajaxEndpoints.includes(event['currentTarget'].responseURL)) {
      window.ajaxEndpoints.push(event['currentTarget'].responseURL);
    }
    window.ajaxCalls--;
    switch (window.ajaxCalls) {
    case 0: // when ajax calls finish this runs
      addData(window.ajaxEndpoints);
    break;
    }
     });
    origOpen.apply(this, arguments);
    }
   }

添加数据功能 - 用于向某些后端发送数据。

function addData(arr, origOpen) { 
   XMLHttpRequest.prototype.open = origOpen;
   axios.post('url', data)
  .then((res) => console.log(res))
  .catch((err) => console.log(err));
}