У меня проблемы с пониманием javaScript promises
. Я написал следующий код:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Я сразу вижу это в моей консоли разработчика Chrome:
Но после того, как я подожду 5 секунд, сообщение автоматически изменится на черный, как показано ниже:
Я никогда раньше не видел такого поведения между моим кодом javaScript и консолью разработчика, где мой код javaScript может «изменять существующее содержимое» в консоли разработчика.
Поэтому я решил посмотреть, возникает ли такая же ситуация resolve
, написав этот код:
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
Но в этой ситуации моя консоль разработчика ничего не показывает, пока через 5 секунд она не распечатывается hello world
.
Почему resolve
и reject
обработаны таким образом , по- разному с точки зрения , когда они вызываются?
EXTRA
Я также написал этот код:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);
Это приводит к нескольким выводам на консоль разработчика. Ошибка красного цвета в момент времени 0, красный цвет errors hello world
становится черным в момент времени 5 секунд с текстом , затем новое сообщение об ошибке в момент времени 6 секунд errors 2 hello world
, затем красное сообщение об ошибке в момент времени 7 секунд. Теперь я очень озадачен тем, сколько раз reject
действительно вызывается .... Я потерян ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
может быть более идиоматически и кратко написано какvar p = Promise.reject(Error("hello world"));
:-)Ответы:
Вау, это действительно круто. Я никогда не видел, чтобы консоль делала это раньше. ( Хотя есть и другие формы динамического поведения, так что ...) Вот что происходит:
В первом случае выполнение кода за пределами
setTimeout
кода вашего обратного вызова завершается, и стек выполнения возвращается так, что выполняется только «программный код » (как его называет спецификация Promises / A +), а не пользовательский код JavaScript (на данный момент). В этот момент обещание отклоняется, и ничто не обработало отклонение, поэтому это необработанное отклонение, и devtools сообщает вам об этом как таковое.Затем , через пять секунд, ваш обратный вызов запускается и подключает обработчик отклонения. На данный момент отказ больше не обрабатывается. Очевидно, Chrome / V8 / devtools работают вместе, чтобы удалить необработанное предупреждение об отказе от консоли. Вместо этого вы видите то, что вы выводите через обработчик отклонений
console.log
. Если вы подключите обработчик отклонения раньше, вы не получите эту необработанную ошибку отклонения.Этого не происходит с выполнением, потому что отсутствие обработки выполнения не является ошибкой. Не обрабатывается отказ.
источник