Search code examples
javascriptajaxwordpressfetch

Decide when both Ajax call and fetch has finished


I am developing something that will run a test. One part of the test is done by going to php via ajax and back again to get some things from the server. The other is to fetch things from an external api.

Both things takes around 3-5 seconds each to run depending on some parameters.

I need to know when both cases has finished so I know that the complete test has finished, not just parts of them.

I have tried below but it puts the flag to completed when the Ajax request is done but not the performance test:

function runAutomaticTest() {
    if (isRunningTest) {
      return;
    }  
    isRunningTest = true;
  
    // Run performance test
    var performanceTestPromise = runPerformanceTest(urlToTest);
  
    // Make AJAX call
    var ajaxCallPromise = new Promise((resolve, reject) => {
      jQuery.ajax({
        type: "POST",
        url: ajax_site_url,
        dataType: "json",
        data: {
          action: "automatic-test",
        },
        success: function (response) {
          
        },
        error: function (xhr, status, error) {
          
        },
      });
    });
  
    // Wait for both tasks to complete
    Promise.all([performanceTestPromise, ajaxCallPromise])
      .then(() => {
        isRunningTest = false;
      })
      .catch((error) => {
        isRunningTest = false;
      });
  }

Basic structure of runPerformanceTest:

function runPerformanceTest(url) {
  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);
    });
}

How can I run both tests at the same time (which it does now) and know when both of them has finished?


Solution

  • I made some changes to the code style (for readability), other than that everything is pretty much exactly what you have except I added a return statement to the runPerformanceTest function. In addition, I added resolve(response) in the success callback and reject(error) in the error callback of the Ajax function.

    const runAjaxTest = () => {
      return new Promise((resolve, reject) => {
        jQuery.ajax({
          type: "POST",
          url: ajax_site_url,
          dataType: "json",
          data: {
            action: "automatic-test",
          },
          success: function (response) {
              resolve(response);
          },
          error: function (xhr, status, error) {
              reject(error);
          },
        });
      });
    };
    
    const runPerformanceTest = (url) => {
      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);
        });
    };
    
    const runAutomaticTest = () => {
      if (isRunningTest) {
        return;
      }
    
      isRunningTest = true;
    
      // Wait for both tasks to complete
      Promise.all([runPerformanceTest(urlToTest), runAjaxTest()])
        .then(() => {
          isRunningTest = false;
        })
        .catch((error) => {
          isRunningTest = false;
        });
    };