$ q.reject не работает и возвращается к блоку ошибок в Angular [duplicate]

Если кто-то ищет Linq verson, это работает для меня:

public static IQueryable<BlockVersion> LatestVersionsPerBlock(this IQueryable<BlockVersion> blockVersions)
{
    var max_version_per_id = blockVersions.GroupBy(v => v.BlockId)
        .Select( v => new { BlockId = v.Key, MaxVersion = v.Max(x => x.Version) } );    

    return blockVersions.Where( v => max_version_per_id.Any(x => x.BlockId == v.BlockId && x.MaxVersion == v.Version) );
}
131
задан mikemaccana 6 July 2015 в 18:10
поделиться

4 ответа

Эти два не совсем идентичны. Разница в том, что в первом примере не будет обнаружено исключение, которое было бы выбрано в вашем обработчике success. Поэтому, если ваш метод должен только возвращать разрешенные обещания, как это часто бывает, вам нужен трейлинг-обработчик catch (или еще один then с пустым success параметром). Конечно, может быть, ваш обработчик then не сделает ничего, что потенциально может потерпеть неудачу, и в этом случае использование одного 2-параметра then может быть прекрасным.

Но я считаю, что точка текст, с которым вы связаны, заключается в том, что then в основном полезен против обратных вызовов в его способности связывать множество асинхронных шагов, и когда вы на самом деле это делаете, 2-параметрическая форма then тонко не ведет себя так, как ожидалось, по вышеуказанной причине. Это особенно противоречиво, когда используется средняя цепочка.

Как человек, который сделал много сложного асинхронного материала и натолкнулся на такие углы больше, чем я хотел бы признать, я действительно рекомендую избегать этого анти-шаблона и идти с подход отдельного обработчика.

30
ответ дан acjay 27 August 2018 в 12:56
поделиться

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

Catch Approach

some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })

Преимущества

  1. Все ошибки обрабатываются одним уловом block
  2. Даже выхватывает любое исключение в последующем блоке.
  3. Цепочка множественных обратных вызовов успеха

Недостатки

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

Подход к успеху / ошибкам

some_promise_call()
.then(function success(res) { logger.log(res) },
      function error(err) { logger.log(err) })

Преимущества

  1. Вы получаете мелкозернистый контроль ошибок.
  2. У вас может быть обычная функция обработки ошибок для различных категорий ошибок, таких как ошибка db, ошибка 500 и т. д.

Различия

  1. Если вы хотите обработать ошибки, вызванные обратным вызовом успеха
, вам понадобится еще catch
13
ответ дан Bergi 27 August 2018 в 12:56
поделиться

В чем разница?

Вызов .then() возвращает обещание, которое будет отклонено, если обратный вызов вызывает ошибку. Это означает, что когда ваш успех logger не удался, ошибка будет передана в следующий обратный вызов .catch(), но не с обратным вызовом fail, который идет вместе с success.

Вот элемент управления блок-схема:

control flow diagram of then with two arguments [/g3] control flow diagram of then catch chain [/g4]

Чтобы выразить это в синхронном коде:

// some_promise_call().then(logger.log, logger.log)
then: {
    try {
        var results = some_call();
    } catch(e) {
        logger.log(e);
        break then;
    } // else
        logger.log(results);
}

Второй log (что похоже на первый аргумент .then()) будет выполняться только в том случае, если исключение не было. Маркированный блок и инструкция break кажутся немного странными, это на самом деле то, что python имеет try-except-else для (рекомендуемое чтение!).

// some_promise_call().then(logger.log).catch(logger.log)
try {
    var results = some_call();
    logger.log(results);
} catch(e) {
    logger.log(e);
}

catch ] logger также обрабатывает исключения из вызова журнала регистрации успеха.

Так много для разницы.

Я не совсем понимаю его объяснение, как для try and catch

Аргумент состоит в том, что обычно вы хотите поймать ошибки на каждом шаге обработки и что вы не должны использовать его в цепочках. Ожидается, что у вас есть только один последний обработчик, который обрабатывает все ошибки. В то время как при использовании «антипаттерна» ошибки в некоторых из обратных вызовов не обрабатываются.

Однако этот шаблон на самом деле очень полезно: когда вы хотите обрабатывать ошибки, которые произошли именно на этом шаге, и вы хотите сделать что-то совершенно другим , когда ошибка не была, т.е. когда ошибка невосстановима. Имейте в виду, что это ветвление вашего потока управления. Конечно, это иногда желательно.


Что случилось с этим следующим:

some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })

Чтобы вам пришлось повторить обратный вызов. Вы предпочитаете

some_promise_call()
   .catch(function(e) {
       return e; // it's OK, we'll just log it
   })
   .done(function(res) {
       logger.log(res);
   });

Вы также можете использовать .finally() для этого.

151
ответ дан Community 27 August 2018 в 12:56
поделиться

Вместо слов, хороший пример. Следующий код (если первое обещание разрешено):

Promise.resolve()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

идентично:

Promise.resolve()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)

Но с отклоненным первым обещанием это не идентично:

Promise.reject()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

Promise.reject()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)
-1
ответ дан ktretyak 27 August 2018 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: