Массив из внешней области видимости ошибочно указывается как пустой при использовании во вложенных обещаниях - PullRequest
1 голос
/ 08 января 2020

Я пытаюсь собрать данные асинхронно, используя jQuery и Promise. Вот краткое представление моего кода:

(function () {
    let promises = [], results = [];
    const urls = ["https://cdn.jsdelivr.net/gh/rails/rails/MIT-LICENSE"];
    for (let url of urls) {
        let p = $.get(url).then(
            // The actual job is to parse the response and make new requests
            // but for simplicity I'll just make the same request again here
            () => promises.push(
                $.get(url).then(
                    data => results.push(data))));
        promises.push(p);
    }
    console.log("Start");
    Promise.all(promises).then(function () {
        console.log("Done");
        console.log(results);
    });
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Странно то, что я вижу заметную задержку до запуска console.log, но в моей консоли появляется пустой массив. Однако, если я сразу введу results, я смогу увидеть все ожидаемое там. Я тоже не вижу ошибок.

Я полагаю, что это как-то связано с тем, что я вкладываю обещания в обещания, но я не знаю, как выследить ошибку.

1 Ответ

1 голос
/ 08 января 2020

Вот как обрабатываются обещания с использованием Promise.all . Pu sh обещание в массив. Чем разрешить этот массив обещаний, который даст массив значений.

var promises = [];
for (let url of urls) {
    // Save promise in p
    let p = $.get(url)
    // push promise p in promises array
    promises.push(p);
}
// resolve all promises
Promise.all(promises).then(function (results) {
    console.log(results);
});

Исходный код не работает, поскольку для каждого URL-адреса значение, сохраненное в p, является обещанием, которое будет преобразовано в неопределенное, как тогда ничего не возвращает.

(function () {
let promises = [], results = [];
const urls = ["https://cdn.jsdelivr.net/gh/rails/rails/MIT-LICENSE"];
for (let url of urls) {
    let p = $.get(url).then(d => {
    results.push(d);
    // return the value
    return d;
    });
    promises.push(p);
}
console.log("Start");
console.log(promises);
Promise.all(promises).then(function () {
    console.log("Done");
    console.log(results);
});
})();

Это будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...