Использование Promise all для заполнения выпадающих списков - PullRequest
1 голос
/ 20 марта 2020

Я использую Promises, чтобы автоматически заполнять мои выпадающие списки при загрузке страницы (у меня есть несколько раскрывающихся списков на странице).

Вот код, который я использую для возврата следующего:

$(document).ready(function(){
    var urls = ['getBrands', 'getTags'];
    Promise.all(urls.map(u=>fetch(u))).then(
        responses => Promise.all(responses.map(res => res.json()))
    ).then(
        texts=>console.log(texts)
    ).then(
        result => console.log(result[0]) //This is where the error is
    )
});

Это печатает ответ на консоль правильно, но выдает ошибку, когда я пытаюсь прочитать отдельный результат. Ошибка Uncaught(in promise) TypeError: cannot read property '0' of undefined

1 Ответ

4 голосов
/ 20 марта 2020

Проблема в том, что ваш первый обработчик выполнения возвращает undefined, который становится значением выполнения обещания, которое он возвращает.

Если вы просто удалите его, ваш второй обработчик выполнения увидит значения.

$(document).ready(function(){
    var urls = ['getBrands', 'getTags'];
    Promise.all(urls.map(u=>fetch(u))).then(
        responses => Promise.all(responses.map(res => res.json()))
    ).then(
        result => console.log(result[0])
    )
});

В качестве альтернативы пусть он вернет то, что получил:

$(document).ready(function(){
    var urls = ['getBrands', 'getTags'];
    Promise.all(urls.map(u=>fetch(u))).then(
        responses => Promise.all(responses.map(res => res.json()))
    ).then(texts => {
        console.log(texts);
        return texts;
    }).then(
        result => console.log(result[0])
    )
});

Примечание: этот код нарушает одно из правил обещаний, а именно:

Обработайте отклонение или передайте цепочку обещаний тому, что будет.

Возможно, вы захотите добавить обработчик отклонения через .catch.

Примечание 2: Предположим, fetch это стандарт fetch, в вашем коде отсутствует проверка на успешность. Это легенда в API fetch (я пишу об этом здесь ). Исправление:

    Promise.all(
        urls.map(u=>fetch(u).then(response => {
            if (!response.ok) {
                throw new Error("HTTP error " + response.status);
            }
            return res.json();
        }))
    ).then(texts => {

Обратите внимание, что это также устраняет необходимость во втором Promise.all, но обрабатывает каждый fetch отдельно ранее.

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