Одно Обещание, вызывающее неизвестное (динамическое) число асинхронных методов в последовательности

1

Я хочу создать одно Promise, которое внутренне вызывает последовательность асинхронных методов в последовательности и возвращает результаты этих методов, конкатенированные в упорядоченном массиве, как только последний метод вернется.

Я пытался это сделать:

const getArray = function (thisArray) {
    return new Promise ( function (resolve, reject) {
        if (thisArray.length < 3) {
            setTimeout(function() {
                console.log('adding element');
                thisArray.push(thisArray.length);
                getArray(thisArray);
            },  1000); 
        } else {
            console.log(thisArray);
            console.log('resolving');
            resolve(thisArray);
        }
    });
}

getArray([]).then(function(data) {
    console.log('thened');
    console.log(data);
})

но он никогда не называет then(). Как я могу это сделать?

  • 0
    Некоторые ответы на Как вернуть ответ от асинхронного вызова? адрес разрешает ряд подобных обещаний (и параллельных тоже).
  • 0
    Мне непонятно, как этот код связан с вашим описанием того, что вы пытаетесь сделать.
Показать ещё 3 комментария
Теги:
promise

1 ответ

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

Вы не за горами, вы просто должны быть уверены в том, что будете называть resolve для каждого new Promise. Если вы все еще строите массив, вы передаете полученное обещание из вашего рекурсивного вызова getArray; в противном случае вы передаете массив:

const getArray = function(thisArray) {
    return new Promise((resolve, reject) => {
        if (thisArray.length >= 3) {
            // All done
            resolve(thisArray);
        } else {
            // Do something async...
            setTimeout(() => {
                // ...add the result
                console.log('adding element');
                thisArray.push(thisArray.length);
                // ...and recurse
                resolve(getArray(thisArray));
            }, 1000);
        }
    });
}

getArray([]).then(data => {
    console.log('done');
    console.log(data);
});

Это немного чище, если вы getArray функцию, выполняющую работу async от getArray, и убедитесь, что функция, выполняющая работу async, возвращает обещание. Для наших целей мы можем просто обернуть setTimeout в обертке Promise:

const setTimeoutP = (cb, delay) => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(cb());
        }, delay);
    });
};

затем:

const getArray = thisArray => {
    if (thisArray.length >= 3) {
        return Promise.resolve(thisArray);
    }
    return setTimeoutP(() => {
        console.log("adding element");
        thisArray.push(thisArray.length);
    });
};

Живая копия:

const setTimeoutP = (cb, delay) => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(cb());
        }, delay);
    });
};

const getArray = thisArray => {
    if (thisArray.length >= 3) {
        return Promise.resolve(thisArray);
    }
    return setTimeoutP(() => {
        console.log("adding element");
        thisArray.push(thisArray.length);
        return getArray(thisArray);
    }, 1000);
};

getArray([]).then(data => {
    console.log('done');
    console.log(data);
});

Ещё вопросы

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