skip to Main Content

Context: asynchronous tasks management in Django with Celery and Redis.

I have a function that sends a POST request in Ajax. The server returns a task id.

With the task id I launch another function just after the POST request to fetch the task status in order to check if the worker has executed the task successfully.

Problem: I succeed in doing the polling with javascript and log the results. But at the end my function doesn’t returns the correct data (the one in the if statement). It’s as if the object returned by the if statement is ignored.

It’s the first time I write such a function. Any help would be much appreciated 🙏

Code

function cancelSimcard() {
  const cancellationLink = document.getElementById("cancellationLink");

  return {
    notificationOpen: false,
    message: "à remplacer",

    async sendCancellationRequest() {
      const data = await fetch(cancellationLink.dataset.url, {
        method: "POST",
      });
      const result = await data.json();
      const status = await getStatus(result.task_id);
    },
  };

  async function getStatus(task_id) {
    const statusData = await fetch(`/parc/task_status/${task_id}`, {
      method: "GET",
    });
    const statusResult = await statusData.json();

    if (statusResult.task_status === "SUCCESS") {
      console.log("DATA FROM SUCCESS BLOCK", statusResult);
      return statusResult;
    } else {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      await getStatus(statusResult.task_id);
    }
    console.log("DATA AT THE END", statusResult);
  }
}

Console result:

enter image description here

**I’m trying to get the data from the success block to pass it in sendCancellationRequest() function. **

2

Answers


  1. The recursive calls are being made, but the result is not being returned back to the original caller as mentioned in the comment, therefore, you need to be sure that the the result of the recursive call is returned properly:

    function cancelSimcard() {
      const cancellationLink = document.getElementById("cancellationLink");
    
      return {
        notificationOpen: false,
        message: "à remplacer",
    
        async sendCancellationRequest() {
          const data = await fetch(cancellationLink.dataset.url, {
            method: "POST",
          });
          const result = await data.json();
          const status = await getStatus(result.task_id);
          return status; // return the final status back
        },
      };
    
      async function getStatus(task_id) {
        const statusData = await fetch(`/parc/task_status/${task_id}`, {
          method: "GET",
        });
        const statusResult = await statusData.json();
    
        if (statusResult.task_status === "SUCCESS") {
          console.log("DATA FROM SUCCESS BLOCK", statusResult);
          return statusResult;
        } else {
          await new Promise((resolve) => setTimeout(resolve, 1000));
          let finalResultesult = await getStatus(statusResult.task_id); 
          return finalResultesult // return the result 
        }
      }
    }
    
    Login or Signup to reply.
  2. Your getStatus function doesn’t return anything when executing the else block, so it returns undefined. In other words, whatever the recursive call of getStatus returns, it is ignored, and undefined is returned instead.

    This kind of polling can be implemented with a loop instead of recursion, which lowers the likelihood of making such a mistake:

      // Define this once for all:
      const delay = ms => new Promise((resolve) => setTimeout(resolve, ms));
    
      async function getStatus(task_id) {
        while (true) { // Loop
          const statusData = await fetch(`/parc/task_status/${task_id}`, {
            method: "GET",
          });
          const statusResult = await statusData.json();
          if (statusResult.task_status === "SUCCESS") {
            console.log("DATA FROM SUCCESS BLOCK", statusResult);
            return statusResult;
          }
          await delay(1000);
        }
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search