简体   繁体   中英

Recursive promise not resolving

I have a function that fetches some data. If data is not available (it becomes available after some short time), it returns null. I created a function, that returns promise, which is wrapped around logic that fetches data and checks if it is is available - if not, it calls itself:

Foo.prototype.fetchDataWrapper = function () {
    return new Promise((resolve, reject) => {
        const data = fetchData();
        if (data) {
            resolve(data)
        } else {
            setTimeout(() => {
                return this.fetchDataWrapper()
            }, 100)
        }
    })
}

Problem is, that despite data is fetched correctly, this promise never resolves. What am I doing wrong?

Your return this.fetchDataWrapper() is returning from the timer callback , no fetchDataWrapper . fetchDataWrapper has already returned. Instead, pass that promise into resolve :

Foo.prototype.fetchDataWrapper = function () {
    return new Promise((resolve, reject) => {
        const data = fetchData();
        if (data) {
            resolve(data);
        } else {
            setTimeout(() => {
                resolve(this.fetchDataWrapper()); // *****
            }, 100);
        }
    })
};

When you pass a promise to resolve , it makes the promise resolves belong to resolve or reject based on the promise you pass to it.

(I've also added some missing semicolons to that code. I recommend being consistent with semicolons: Either rely on ASI or don't, both don't mix the two. Also recommend not relying on ASI, but that's a style choice.)


Side note: It would probably make sense to reject after X attempts, perhaps:

Foo.prototype.fetchDataWrapper = function (retries = 5) {
// *** Declare retries param with default -^^^^^^^^^^^
    return new Promise((resolve, reject) => {
        const data = fetchData();
        if (data) {
            resolve(data);
        } else {
            if (retries) { // *** Check it
                setTimeout(() => {
                    resolve(this.fetchDataWrapper(retries - 1));
                    // *** Decrement and pass on -^^^^^^^^^^^
                }, 100);
            } else {
                reject(); // *** Reject
            }
        }
    })
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM