Promise.all получает необработанный отказ - PullRequest
0 голосов
/ 28 мая 2019

Я использую Promise.all и улавливаю ошибку, но все еще получаю необработанное отклонение

const Promise = require('bluebird');

function sleep(milis) {
return new Promise(function(resolve, reject) {
    if (milis == 1000) {
        console.log('Rejecting millis', milis)
        setTimeout(() => {
            reject('Got error')
        }, milis);

    } else {
        console.log('Processing millis', milis)
        setTimeout(() => {
            resolve(milis);
        }, milis);

    }
});
}

function test() {

try {
    let lists = [2000, 1000, 3000]
    Promise.all(
            lists.map(record => {
                try {
                    sleep(record)
                } catch (err) {
                    console.log('Error inside catch block1', err)
                    throw err
                }
            })
        ).then(data => {
            console.log('Resolved', data)
        })
        .catch(err => {
            console.log('Error inside catch block2', err)
            throw err

        });

} catch (err) {
    console.log('Error inside catch block3', err)
}
}


test();

После использования блока перехвата почему все еще получается необработанное отклонение.Любая помощь приветствуется.Но если я использую async, то не получаю необработанного отказа.

Ответы [ 3 ]

1 голос
/ 28 мая 2019

Причина в том, что вы не обрабатываете ошибку в этом sleep методе.Это должно выглядеть так.

function sleep(milis) {
return new Promise(function (resolve, reject) {
    if (milis == 1000) {
        console.log('Rejecting millis', milis)
        setTimeout(() => {
            reject('Got error')
        }, milis);

    } else {
        console.log('Processing millis', milis)
        setTimeout(() => {
            resolve(milis);
        }, milis);

    }
 }).catch(error => {
    console.log(error);
 })
}
1 голос
/ 28 мая 2019

Есть несколько проблем с вашим кодом, давайте рассмотрим их по очереди:

Во-первых

Когда вы отображаете свой массив lists, вы никогда не вернете обещание, которое вы получили отваша sleep() функция.Это означает, что вы предоставляете Promise.all() массив, заполненный undefined.Promise.all() рассматривает значения, которые не являются обещаниями, как разрешенное обещание, поэтому ваше Promise.all() всегда будет разрешаться независимо от того, разрешают или отклоняют обещания, созданные sleep().Это также означает, что ничто не ловит отклоненное обещание от sleep(), и именно поэтому ваш сценарий в настоящее время получает необработанные отклонения обещания.
Вы исправляете это, возвращая обещание правильно с помощью return sleep(record).Но этого будет недостаточно, чтобы избавиться от всех необработанных отклонений обещаний, поэтому давайте двигаться дальше ...

Во-вторых

Вы завернули свои вызовы на sleep() в блоке try-catch,Если вы не используете async-await, блок try-catch будет , а не ловить отклоненные обещания.В этом случае он будет отлавливать только ошибки, возникшие при создании обещания.Это нормально, если это было ваше намерение, но если вы хотели поймать отклоненные обещания, это не сработает.

В-третьих

Вы подключили обработчик catch() к вашему Promise.all(),В отличие от вышеупомянутого try-catch, он фактически заботится о любых отклоненных обещаниях.Однако вы повторно выдает ошибку в этом обработчике, что означает, что цепочка обещаний все равно будет отклонена.Вы завернули Promise.all() в другой блок try-catch, но, как уже упоминалось, это не позволяет отменить отклоненные обещания, поэтому все еще отклоненное обещание в конечном итоге будет обработано.
В этом случае вам просто не следует повторно выбрасыватьошибка в вашем последнем обработчике catch(), так как я не вижу в этом смысла.Если вам по какой-либо причине необходимо перебросить его, вам нужно добавить еще один обработчик catch() позже в цепочке.

1 голос
/ 28 мая 2019

TL; DR: throw err внутри .catch обработчики не попадают ни в какие другие catch в вашем коде, поэтому вы получаете необработанное отклонение обещания.

Прежде всего, в этом фрагменте кода

lists.map(record => {
  try {
    sleep(record)
  } catch (err) {
    console.log('Error inside catch block1', err)
    throw err
  }
})

результат .map будет [undefined, undefined, undefined], так как функция не возвращает никакого значения. Вам нужно написать return sleep(record), если вы хотите, чтобы он возвращал обещание для каждого элемента списка.

Затем обратите внимание, что основной блок catch выполняется перед обработчиками .then / .catch Promise.all. Если вы добавите console.log после вашего основного catch блока, вы увидите это. Это означает, что исключения, которые вы повторно генерируете в своих обработчиках .catch, ничем не перехвачены и отображаются как необработанные.

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