skip to Main Content

I tried to extend a promise while its resolution is ongoing.

(async () => {
  var p4 = Promise.resolve([3]);
  var rec = (s) => {
    let x = s.pop();
    s.push(x - 1);
    if (x > 0) {
      console.log(x);
      p4.then(rec);
    }
  };
  p4.then(rec);
  console.log("result", (await p4)[0]);
})();

My problem is: the recursion works as expected (3, 2, 1 is printed), but the result is 2 instead of 0. It seems to me that the last line just sees the first step of the recursion. It follows only those continuations, which have been added till the resolution starts. Those which are added while the resolution is ongoing are ignored. How to fix this?

2

Answers


  1. p4 and p4.then are different promises, since then() returns a new promise. Use then() together with await to wait for your then chain resolution.

    Also you should return from rec() either a chained promise created again with p4.then() or [0] as the final chain result. Otherwise your promise is resolved immediately without chaining:

    (async () => {
      var p4 = Promise.resolve([3]);
      var rec = (s) => {
        let x = s.pop();
        s.push(x - 1);
        if (x > 0) {
          console.log(x);
          return p4.then(rec);
        }
        return [0];
      };
    
      console.log("result", (await p4.then(rec))[0]);
    })();
    Login or Signup to reply.
  2. Instead of working with Promise manually, try using async and await like this:

    async function rec(s) {
        let x = s.pop();
        s.push(x - 1);
        if (x > 0) {
            console.log(x);
            return await rec(s);
        } else return s;
    }
    console.log("result", (await rec([3]))[0]);
    // 3
    // 2
    // 1
    // result -1

    Stackless version:

    async function rec(s) {
        for (;;) {
            let x = s.pop();
            s.push(x - 1);
            if (x > 0) console.log(x);
            else return s;
        }
    }
    console.log("result", (await rec([3]))[0]);

    The snippets refuse to run, but I promise it works in a browser console.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search