Search code examples
typescriptrecursionpromisees6-promise

create a promise which encompass a recursive function


I'm writing a simple recursive function that is calling a function driver that returns a promise. And my aaa function has to return a Promise at the end of the calls.

So this code is the simplification of my issue:

Code:

function aaa(index) {
      driver(index)
      .then(index => {
            if (index < 100)
                  aaa(index);
            else
                  console.log('finito' + index);     
      })

}

function driver(index) {
      return new Promise(resolve => {
            resolve(index + 1);
      });
}

aaa(0);

My Solution:

function aaa(index) {
      console.log(index);
      return Promise.resolve(index)
            .then((index) => {
                  driver(index)
                        .then( index => {
                              if (index < 100)
                                    return aaa(index);
                              else
                                    return Promise.resolve(index);
                        });
            });
}

function driver(index) {
      return new Promise(resolve => {
            resolve(index + 1);
      });
}

function doTheThing() {
  Promise.resolve(0).then(aaa)
  .then(()=>{
    alert('end');
  });
}

doTheThing();

But I still have an editor warning in the last then of the aaa function which is:

Argument of type '(index: {}) => Promise<void> | Promise<{}>'
is not assignable to parameter of type '(value: {}) => void | PromiseLike<void>'.
  Type 'Promise<void> | Promise<{}>' is not assignable to type 'void | PromiseLike<void>'.
    Type 'Promise<{}>' is not assignable to type 'void | PromiseLike<void>'.

Solution

  • my aaa function has to return a Promise at the end of the calls

    ... That is exactly what isn't happening in your first code. But also the version with doTheThing runs into an error because there is no return in the line with driver(index).

    For it to return a promise, you can stick with the first version of your code, but add return in two places:

    function aaa(index) {
        return driver(index).then(index => {
    //  ^^^^^^ (1)
            if (index < 100) {
                return aaa(index);
    //          ^^^^^^ (2)
            } else {
                console.log('finito' + index);     
            }
        })
    }
    
    function driver(index) {
        return new Promise(resolve => {
            resolve(index + 1);
        });
    }
    
    function doTheThing() {
        Promise.resolve(0).then(aaa).then(() => {
            console.log('end');
        });
    }
    
    doTheThing();

    Note that in doTheThing it is not really necessary to do Promise.resolve(0).then(aaa).then. You can just do aaa(0).then.