Рекурсивное обещание не разрешается

1

У меня есть функция, которая извлекает некоторые данные. Если данные недоступны (он становится доступным через некоторое короткое время), он возвращает значение null. Я создал функцию, которая возвращает обещание, которое обернуто вокруг логики, которая извлекает данные и проверяет, доступна ли она - если нет, она вызывает себя:

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

Проблема в том, что, несмотря на то, что данные получены правильно, это обещание никогда не решается. Что я делаю неправильно?

  • 2
    Что возвращает ваш метод извлечения?
  • 0
    Я спрашиваю то же самое :-). Это синхронно? (возможно нет). Я имею в виду fetchData(); , Можете ли вы показать нам эту функцию?
Показать ещё 1 комментарий
Теги:

1 ответ

1
Лучший ответ

Ваше return this.fetchDataWrapper() возвращается из обратного вызова таймера, без fetchDataWrapper. fetchDataWrapper уже вернулся. Вместо этого передайте это обещание в 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, а на выбор стиля. )


Боковое замечание. Вероятно, было бы целесообразно отказаться от попыток 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
            }
        }
    })
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню