Search code examples
javascriptes6-promise

Trying to set a recursive function inside a promise


let cancelDownload = true
const delay = () => {
    return new Promise(() => {
            if (cancelDownload === true){
                setTimeout(() => {
                    console.log('Delaying...');
                    delay();
                }, 1000);
            }
            else return null;
            });
};
const cancelJob = async() => {
    for(let i = 6; i>0; i--){
        console.log('inside for ',i);
        setTimeout(()=>{
            cancelDownload = false
        },4000)
        await delay()
        console.log('aaaaaaaa');
        console.log(`the number is ${i}`);
    }
}

cancelJob()

I am trying to write a delay function whereby once the condition is met delay is removed and all code is resumed but it seems that once the delay is done the code exits without executing the last two console logs

Console log message below


Solution

  • No recursion needed. Instead, you can:

    1. Use setInteval to check your condition every second.
    2. When the condition is correct, you need to resolve the promise.
    3. Use clearInterval.

    let cancelDownload = true
    const delay = () => {
        let intervalId;
        return new Promise((resolve, reject) => {
          const check = () => {
            if (cancelDownload === true){
                console.log('Delaying...');
            } else  {
              clearInterval(intervalId);
              resolve();
            }
          }
          //check immediately
          check();
          //then check every second afterwards
          intervalId = setInterval(check, 1000);
        });
    };
    const cancelJob = async() => {
        for(let i = 6; i>0; i--){
            console.log('inside for ',i);
            setTimeout(()=>{
                cancelDownload = false
            },4000)
            await delay()
            console.log('aaaaaaaa');
            console.log(`the number is ${i}`);
        }
    }
    
    cancelJob()

    This can be generalised a bit in the following fashion - instead of hard-coding the condition, supply it as a callback. Then you can have a delay function without using global variables and it can wait for different things, not just one single variable.

    const delayWhile = shouldWait => () => {
        let intervalId;
        return new Promise((resolve, reject) => {
          const check = () => {
            if (shouldWait()){
                console.log('Delaying...');
            } else  {
              clearInterval(intervalId);
              resolve();
            }
          }
          //check immediately
          check();
          //then check every second afterwards
          intervalId = setInterval(check, 1000);
        });
    };
    
    const cancelJob = async() => {
        let cancelDownload = true;
        const delay = delayWhile(() => cancelDownload);
        
        for(let i = 6; i>0; i--){
            console.log('inside for ',i);
            setTimeout(()=>{
                cancelDownload = false
            },4000)
            await delay()
            console.log('aaaaaaaa');
            console.log(`the number is ${i}`);
        }
    }
    
    cancelJob()