С обещанием, почему браузеры возвращают отклонение дважды, а не разрешение дважды? - PullRequest
10 голосов
/ 08 октября 2019

У меня проблемы с пониманием javaScript promises. Я написал следующий код:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log(e)),5000);

Я сразу же вижу это в консоли разработчика Chrome: enter image description here

Но через 5 секунд сообщение автоматическименяется на черный, как показано на этом изображении: enter image description here

Я никогда раньше не видел такого поведения между моим кодом 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, красный цвет становится черным в момент времени 5 секунд с текстом errors hello world, затем новое сообщение об ошибке в момент времени 6 секунд errors 2 hello world, затем красное сообщение об ошибке в момент времени 7 секунд. Теперь я очень озадачен тем, сколько раз на самом деле вызывается reject .... Я потерян ...

1 Ответ

11 голосов
/ 08 октября 2019

Ого, это действительно круто. Я никогда не видел, чтобы консоль делала это раньше. (Он имеет другие формы динамического поведения, хотя, так что ...) Вот что происходит:

В первом случае выполнение кода за пределами вашего setTimeout кода обратного вызова завершаетсяи стек выполнения возвращается так, что выполняется только « код платформы » (как его называет спецификация Promises / A +), а не пользовательский код JavaScript (на данный момент). В этот момент обещание отклонено, и ничто не обработало отклонение, поэтому это необработанное отклонение , и devtools сообщает вам об этом как таковой.

Затем , пятьчерез несколько секунд ваш обратный вызов запускается и присоединяет обработчик отклонения. На данный момент отказ больше не обрабатывается. Очевидно, что Chrome / V8 / devtools работают вместе, чтобы удалить необработанное предупреждение об отказе из консоли. Вместо этого вы видите то, что вы выводите в обработчике отклонения через console.log. Если вы подключите обработчик отклонения раньше, вы не получите эту необработанную ошибку отклонения.

Этого не происходит с выполнением, потому что отсутствие обработки выполнения не является условием ошибки. Не обрабатывается отклонение.

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