3

I am working with some asynchronous functions in javascript, but I am facing a problem, that I already posted here but that was a bit unpractical experience for everyone. Now, I made a simple constructor function with same member functions inside and returned a value, but seems like same problem to me, I tried my best but I don't know what is the problem, if you run this code then You can check what I want. Here's the demo link on JSfiddle, where you can see the results on console.

This is my Code

function Test() {
  this.init = async function() {
    var count = 0,
      page_job_details = null;

    async function waitMore() {
      console.log("Wait more loaded - " + (count + 1) + "...");
      let p = new Promise(function(res, rej) {
        setTimeout(async function() {
          if (count === 2) {
            res({
              page_job_details: "khan"
            });
          } else {
            count++;
            waitMore();
          }
        }, 2000);
      });
      var res = await p;
      if (res.page_job_details === '' || res.page_job_details === 'undefined' || res.page_job_details === null) {
        console.log("waiting more...");
        waitMore();
      } else {
        console.log("Response is : " + res.page_job_details);
        return res;
      }
    }
    var khan;
    await waitMore().then(function(r) {
      console.log(r);
      khan = r;
    });
    return khan;
  }
}
new Test().init().then(function(res) {
  console.log(res);
})

When you comment out the conditions within the setTimeout() and simply res({page_job_details:"khan"}); then you'll get the results in the new Test().init().then(function(res){ console.log(res); }). Otherwise not, and that's the main problem.

5
  • Thanks, can you explain what sort of output you were expecting instead? Commented Nov 23, 2018 at 6:17
  • @CertainPerformance I am expecting the answer in the res, when the Test().init() is called. Commented Nov 23, 2018 at 6:18
  • You're receiving "khan" at the end of the promise, is not what you want? Commented Nov 23, 2018 at 6:20
  • @MiguelAngel It's not being chained to the end .init().then section Commented Nov 23, 2018 at 6:22
  • I want the results returned by the init() @MiguelAngel Commented Nov 23, 2018 at 6:22

2 Answers 2

3

One of the issues is that you are not returning the result of the recursive call from within the promise.

Instead of just calling it recursively

waitMore();

you seem to expect the result of the recursive call to be returned down the pipeline

res(waitMore());

function Test() {
  this.init = async function() {
    var count = 0,
      page_job_details = null;

    async function waitMore() {
      console.log("Wait more loaded - " + (count + 1) + "...");
      let p = new Promise(function(res, rej) {
        setTimeout(async function() {
          if (count === 2) {
            res({
              page_job_details: "khan"
            });
          } else {
            count++;
            res(waitMore());
          }
        }, 2000);
      });
      var res = await p;
      if (res.page_job_details === '' || res.page_job_details === 'undefined' || res.page_job_details === null) {
        console.log("waiting more...");
        waitMore();
      } else {
        console.log("Response is : " + res.page_job_details);
        return res;
      }
    }
    var khan;
    await waitMore().then(function(r) {
      console.log(r);
      khan = r;
    });
    return khan;
  }
}
new Test().init().then(function(res) {
  console.log(res);
})

Sign up to request clarification or add additional context in comments.

2 Comments

Perfect Results, can you explain it a bit to me technically; why the results of console.log("Response is : " + res.page_job_details); is three times displayed ? in the else part .
Three seems to be the level of your recursion.
2

There are two issues:

  • Inside waitMore's setTimeout, res is only called if count === 2. Otherwise, the created promise never resolves, and whatever might be awaiting waitMore() will never resolve - instead, that thread will remain suspended forever. You can fix this by calling res regardless of whether count is 2 or not - if the count is less than 2, call res with another invocation of waitMore:

    res(waitMore());
    
  • On the level of the this.init function, in the case that you need to wait more, you need to await waitMore() (and put the response in a new variable that gets returned) so as to chain the Promise properly:

    if (res.page_job_details === '' || res.page_job_details === 'undefined' || res.page_job_details === null) {
      console.log("waiting more...");
      const newRes = await waitMore();
      return newRes;
    } 
    

function Test() {
  this.init = async function() {
    var count = 0,
      page_job_details = null;

    async function waitMore() {
      console.log("Wait more loaded - " + (count + 1) + "...");
      const p = new Promise((res, rej) => {
        setTimeout(() => {
          if (count === 2) res({ page_job_details: "khan" });
          else {
            count++;
            res(waitMore());
          }
        }, 2000);
      });
      const res = await p;
      if (res.page_job_details === '' || res.page_job_details === 'undefined' || res.page_job_details === null) {
        console.log("waiting more...");
        const newRes = await waitMore();
        return newRes;
      } else {
        console.log("Response is : " + res.page_job_details);
        return res;
      }
    }
    var khan;
    await waitMore().then(function(r) {
      console.log(r);
      khan = r;
    });
    console.log('about to return from init')
    return khan;
  }
}
new Test().init().then(function(res) {
  console.log('in init callback')
  console.log(res);
})

1 Comment

Perfect, Thank you for your answer !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.