Что определяет, что отказ от обещания не обрабатывается в node.js (console / script)? - PullRequest
0 голосов
/ 25 октября 2018

Javascript Обещания, если мне пришлось чрезмерно упрощать, на мой взгляд, «способ действовать на вещи» позже , запланированный с помощью метода .then() ».

После выполнения следующих действий в моемтерминал:

BASE$> node
> var promise = Promise.reject("reason 42");

Поэтому я был удивлен, увидев этот результат:

> (node:8783) UnhandledPromiseRejectionWarning: reason 42
(node:8783) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:8783) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

, потому что я собирался написать.

> promise.catch(console.log);

Мотивация этого вопроса заключается в следующем:
Могу ли я быть достаточно уверенным, что node.js только извлекает из этого предупреждения (и угрозы «в будущем я полностью спасу» из-закод выполняется пошагово в консоли node.js / REPL ?

Как node.js уже пришел к выводу, что отказ от обещания должен был быть обработан?

Поэтому я проверил следующее, чтобы работать по-разному

  1. Оценка "одного и того же кода", объединенного в одной итерации REPL:
    var promise = Promise.reject("reason 42"); promise.catch(console.log);
  2. Оценка "того же кода" изфайл (например, tmp.js) с содержимым
    var promise = Promise.reject("reason 42") 
    promise.catch(console.log);`)
    
    через node tmp.js

, оба с ожидаемым выводом "reason 42", не выдавая никакого предупреждения, как показано выше.

Следовательно, как это работает? Можно ли подтвердить мое предположение, что определение необработанного обещания в консоли узла REPL отражает отражение достижения в каждой итерации цикла REPL?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Я хотел бы расширить ответ @estus, особенно первое предложение:

Чтобы отклонение обещания считалось обработанным, оно должно быть связано с catch или затем с двумя аргументами на одном и том жегалочка.

Я бы не полностью с этим согласился.Я бы сказал, что каждое обещание, где вызывается then или catch, прекрасно, , но при вызове этих методов вы создаете новые обещания, и они только что унаследовали проблему.

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

const root = Promise.reject("reason 42");

const a = root.then(value => value*2)
              .then(...);

const b = root.then(value => value*3)
              .then(...);

Итаквы строите цепочку / дерево обещаний;происходит ошибкаОшибка распространяется на дочерние обещания в этом дереве, ... Если эта (или любая другая) ошибка достигает любого листового обещания (без перехвата где-нибудь вдольлиния) вы получите UnhandledPromiseRejectionWarning.

Есть миллионы вещей, которые вы можете сделать с обещаниями, как вы их цепочку / ветвление и как / где вы ловите свои ошибки, ...Итак, лучшее резюме, которое я могу вам дать по этому вопросу:

Поскольку Promises все время, у вас есть время, пока Ошибка достигнет конца цепочки, до catch it.

Могу ли я быть разумно уверенным, что node.js извлекает только эти предупреждения (и угрозу «в будущем я полностью спасу» из-за пошагового выполнения кода в консоли node.js

Да

0 голосов
/ 25 октября 2018

Для того чтобы отклонение обещания считалось обработанным, его следует объединить в цепочку catch или then с двумя аргументами на одном тике.

Это приведет к UnhandledPromiseRejectionWarning:

var promise = Promise.reject("reason 42");

setTimeout(() => {
  promise.catch(console.error);
});

Это не приведет к UnhandledPromiseRejectionWarning:

var promise = Promise.reject("reason 42");
promise.catch(console.error);

Асинхронно оцененные строки в REPL Node.js приводят к задержке между ними.Для синхронной оценки строк в порядке их написания можно использовать режим редактора .Или код может быть записан для однозначной оценки как блок:

;{
var promise = Promise.reject("reason 42");
promise.catch(console.error);
}

Или IIFE:

(() => {
var promise = Promise.reject("reason 42");
promise.catch(console.error);
})()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...