递归承诺未解决

时间:2018-10-23 06:44:23

标签: javascript

我有一个获取一些数据的功能。如果数据不可用(短时间后变为可用),则返回null。我创建了一个函数,该函数返回promise,该函数被包裹在获取数据并检查数据是否可用的逻辑周围-如果没有,它将调用自身:

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

问题是,尽管正确地获取了数据,但是这个承诺永远无法解决。我在做什么错了?

1 个答案:

答案 0 :(得分:2)

您的return this.fetchDataWrapper()是从计时器回调返回的,没有fetchDataWrapperfetchDataWrapper已返回。而是将那个承诺传递给resolve

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

当您将承诺传递给resolve时,它会使承诺resolves根据您传递给它的承诺属于或拒绝

((我还向该代码中添加了一些缺少的分号。我建议与分号保持一致:要么依靠ASI,要么不依靠ASI,两者都不要混用。也建议不要依靠ASI,但这是一种样式选择。)


旁注:尝试X次后拒绝可能是有意义的,也许:

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
            }
        }
    })
};