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
только тянет за этими предупреждениями (и угрозой "в будущем я полностью заступлю" из-за того, что код запускается поэтапно в console.js console/REPL?
Как node.js
уже пришел к выводу, что отказ от обещаний должен быть необработанным?
Поэтому я тестировал следующее, чтобы работать по-другому
var promise = Promise.reject("reason 42"); promise.catch(console.log);
tmp.js
) с контентом var promise = Promise.reject("reason 42") promise.catch(console.log);')через
node tmp.js
оба дают ожидаемый результат " reason 42
", не представляя предупреждения, как показано выше ранее.
Следовательно, как это получается? Могу ли мое предположение подтвердить, что определение необработанного обещания в консоли REPL
узла является отражением конечного конца в каждой итерации цикла REPL
?
Для того, чтобы отказ от обещания считался обработанным, он должен быть прикован цепью с 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);
Асинхронно оцениваемые строки в Node.js REPL приводят к задержке между ними. Чтобы синхронно оценивать строки в том порядке, в котором они были записаны, можно использовать режим редактора. Или код можно записать так, чтобы его однозначно оценивали как блок:
;{
var promise = Promise.reject("reason 42");
promise.catch(console.error);
}
Или IIFE:
(() => {
var promise = Promise.reject("reason 42");
promise.catch(console.error);
})()
REPL
две итерации не квалифицируются как синхронные , правильно ли я понимаю?
Я хотел бы распространить на @estus ответ, особенно первое предложение:
Для того, чтобы отказ от обещания считался обработанным, он должен быть прикован цепью с уловкой или затем с двумя аргументами на одном тике.
Я не согласен с этим. Я бы аргумент, что каждое обещание, где 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
ее.
Могу ли я быть уверенным, что node.js только тянет за этими предупреждениями (и угрозой "в будущем я полностью заступлю" из-за того, что код запускается поэтапно в консоли node.js
да
catch()
отклонения должен выполняться синхронно, чтобы избежать предупреждения, и b) каждая итерация REPL
консоли node.js не является синхронно больше с предыдущим. +1, как это, однако, выделить еще одну ловушку.
I was therefore supprised to see this result because I was about to write
Он не может читать ваши мысли - в тот момент он даже не подозревал, что с ним будут работать. Таким образом, вместо того, чтобы ждать какое-то неопределенное количество времени и затем проверять, не отклонен ли по-прежнему необработанный запрос, он немедленно выдаст запрос.