Estou tendo problemas para entender o javaScript promises
. Eu escrevi o seguinte código:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Vejo isso imediatamente no meu console do desenvolvedor Chrome:
Mas depois de esperar 5 segundos, a mensagem muda automaticamente para preto como esta imagem:
Nunca vi esse comportamento antes entre meu código javaScript e um console do desenvolvedor, onde meu código javaScript pode "modificar o conteúdo existente" no console do desenvolvedor.
Então eu decidi ver se a mesma situação ocorre resolve
escrevendo este código:
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
Mas nessa situação, meu console do desenvolvedor não mostra nada até 5 segundos depois, para o qual é impresso hello world
.
Por que o resolve
e reject
tratadas de modo diferente em termos de quando eles são chamados?
EXTRA
Eu também escrevi este código:
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);
Isso causa várias saídas para o console do desenvolvedor. Erro vermelho no tempo 0, vermelho muda para preto no tempo 5 segundos com o texto errors hello world
, uma nova mensagem de erro no tempo 6 segundos errors 2 hello world
e uma mensagem de erro vermelha no tempo 7 segundos. Agora estou muito confuso sobre quantas vezes uma pessoa reject
é realmente chamada ... Estou perdida ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
pode ser mais idiomaticamente e concisa escrito comovar p = Promise.reject(Error("hello world"));
:-)Respostas:
Uau, isso é muito legal. Eu nunca tinha visto o console fazer isso antes. ( Porém, ele tem outras formas de comportamento dinâmico, então ...) Aqui está o que está acontecendo:
No primeiro caso, a execução do código de tudo o que estiver fora
setTimeout
do código do retorno de chamada é concluída e a pilha de execução retorna para que apenas o " código da plataforma " (como a especificação Promises / A + o chame) esteja sendo executado, e não o código JavaScript da área do usuário (no momento). Nesse ponto, a promessa é rejeitada e nada lidou com a rejeição; portanto, é uma rejeição não tratada e o devtools a relata como tal.Então , cinco segundos depois, seu retorno de chamada é executado e anexa um manipulador de rejeição. Nesse ponto, a rejeição não é mais tratada. Aparentemente, o Chrome / V8 / devtools trabalha em conjunto para remover o aviso de rejeição não tratada do console. Em vez disso, o que você vê é o que você produz no seu manipulador de rejeições via
console.log
. Se você anexasse o manipulador de rejeição mais cedo, não receberia esse erro de rejeição não tratado.Isso não acontece com o cumprimento porque não lidar com o cumprimento não é uma condição de erro. Não lidar com rejeição é.
fonte