Цикл, пока функция обещания не даст результат

Я надеюсь запустить функцию обещания, пока не получу желаемый результат.

На данный момент я использую рекурсивность вот так:

function pull() {
   dataFactory.pullFunction().then(function(res) {
      pull()       
   })
}

Но это дает мне некоторые ошибки интерфейса / стиля для моей панели загрузки, например.

Я бы сделал что-то вроде этого:

function pull() {
    while (res.status == 'ONGOING') {
        dataFactory.pullFunction().then(function(res) {
            // my stuffs
        })
    }
 }

Но когда я пытаюсь это сделать, pullFunction() никогда не вызывается.

2 ответа

Если вы не можете использовать async/await тогда вы должны использовать функцию, которая вызывает себя. Это не совсем рекурсивная рекурсия, потому что стек вызовов создается не так, как при обычной (синхронной) рекурсии.

Но вам нужно все время придерживаться обещаний. Так что верните обещание и продолжайте использовать then также на начальном вызове pull в остальной части вашего кода.

Вероятно, вы также хотите собрать куски данных, которые вы получаете из ваших пулов, в один набор данных.

Здесь я предполагаю, что у объекта ответа будет атрибут данных с порцией данных.

Вот как это могло бы работать (с фиктивной реализацией pullFunction):

function pull() {
    return (function loop(data) {
        return dataFactory.pullFunction().then ( res => {
            return res.status === 'ONGOING'
                ? loop(data.concat(res.data))
                : data.concat(res.data)
        });
    })([]);
}

// Mock implementation
var dataFactory = {
    pullFunction: function () {
        console.log('pull');
        return new Promise( resolve => {
            setTimeout(_ =>
                resolve({
                    status: Math.random() > 0.7 ? 'DONE' : 'ONGOING',
                    data: [1,2,3,4]
                }),
            500)
        });
    }
}

// test it
pull().then( (data) => {
    console.log('data: ', data);
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Просто создайте isOngoing переменная

let isOngoing = false;
function pull() {
  isOngoing = true;
  dataFactory.pullFunction()
    .then(res => {
      if(<your-condition>) {
        isOngoing = false;
      } else {
        pull();
      }
    })
}

редактировать

Вы имеете дело с асинхронными операциями здесь, вы не можете зациклить его с традиционными while или же for петля. Если ваша среда не позволяет вам использовать async/await функции.

async function pull() {
    while (res.status == 'ONGOING')
        await dataFactory.pullFunction().then(function(res) {
            // my stuffs
        })
}
Другие вопросы по тегам