Home > database >  Writing a Javascript function that resolves a promise when watch source becomes truthy
Writing a Javascript function that resolves a promise when watch source becomes truthy

Time:04-20

I am trying to write a Javascript function that will watch a javascript expression and wait until it becomes truthy and then it will resolve the promise. The problem is that my when function never resolves the promise.

In the end I would like to use this function like this:

let myNumber = 0

setInterval(() => {
    myNumber = myNumber   1
}, 1000)

when(myNumber === 4).then(() => {
    console.log('My number is 4!!')
})

Here is my when() function:

window['when'] = (watchSource: boolean): Promise<any> => {
    return new Promise(resolve => {
        let interval

        interval = setInterval(() => {
            console.log(watchSource) // <--- always false

            if (watchSource === true) {
                clearInterval(interval)
                resolve()
            }
        }, 100)
    })
}

CodePudding user response:

when(myNumber === 4).then(() => {
    console.log('My number is 4!!')
})

The problem with this is that myNumber === 4 is evaluated as false when when() is called, and so false is then assigned to watchSource. Since when() is never called again, a new value for watchSource is never provided and it stays false.


One (of many) ways to solve this is for your watchSource to be a function. This lets you re-execute the condition each time you want to check it.

window['when'] = (watchSource: () => boolean): Promise<any> => {
    return new Promise(resolve => {
        let interval

        interval = setInterval(() => {
            console.log(watchSource()) // <--- always false

            if (watchSource() === true) {
                clearInterval(interval)
                resolve()
            }
        }, 100)
    })
}

Then:

when(() => myNumber === 4).then(() => {
    console.log('My number is 4!!')
})

Playground

CodePudding user response:

The when() is called only once throughout the application unless you call it somewhere else again. So more appropriate logic for your case would be:

let myNumber = 0

const interval = setInterval(() => {
    myNumber = myNumber   1
    if (myNumber === 4) {
        clearInterval(interval);
    }
}, 1000)

If you want to implement some kind of 'watch' handler, I'd recommend using Proxy instead.

  • Related