Atualmente, estou lendo Async Javascript de Trevor Burnham. Este tem sido um grande livro até agora.
Ele fala sobre esse snippet e o console.log serem 'assíncronos' no console Safari e Chrome. Infelizmente, não posso replicar isso. Aqui está o código:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
Se isso fosse assíncrono, eu anteciparia que o resultado seria o resultado dos livros. console.log () é colocado na fila de eventos até que todo o código seja executado, então ele é executado e teria a propriedade bar.
Parece que está sendo executado de forma síncrona.
Estou executando este código errado? O console.log é realmente assíncrono?
javascript
asynchronous
Olá Mundo
fonte
fonte
console.log()
nem sempre mostra o valor anterior. A solução, se isso acontecer com você, é converter tudo o que você está tentandoconsole.log()
em uma string imutável, portanto, não está sujeita a esse problema. Portanto, por experiência própria,console.log()
tem alguns problemas assíncronos provavelmente relacionados ao empacotamento de dados entre os limites do processo. Este não é o comportamento pretendido, mas é algum efeito colateral de comoconsole.log()
funciona internamente (eu pessoalmente considero um bug).Respostas:
console.log
não é padronizado, portanto, o comportamento é bastante indefinido e pode ser alterado facilmente de uma versão para outra das ferramentas de desenvolvedor. É provável que seu livro esteja desatualizado, assim como minha resposta em breve.Para o nosso código, não faz diferença se
console.log
é assíncrono ou não, não fornece nenhum tipo de retorno de chamada ou algo assim; e os valores que você passa são sempre referenciados e calculados no momento em que você chama a função.Não sabemos realmente o que acontece então (OK, poderíamos, já que Firebug, Chrome Devtools e Opera Dragonfly são todos de código aberto). O console precisará armazenar os valores registrados em algum lugar e os exibirá na tela. A renderização acontecerá de forma assíncrona com certeza (sendo estrangulada para atualizações de limite de taxa), assim como as futuras interações com os objetos registrados no console (como propriedades de objeto em expansão).
Portanto, o console pode clonar (serializar) os objetos mutáveis que você registrou ou armazenar referências a eles. O primeiro não funciona bem com objetos grandes / profundos. Além disso, pelo menos a renderização inicial no console provavelmente mostrará o estado "atual" do objeto, ou seja, aquele quando ele foi logado - no seu exemplo, você vê
Object {}
.No entanto, quando você expande o objeto para inspecionar ainda mais suas propriedades, é provável que o console tenha armazenado apenas uma referência ao seu objeto e suas propriedades, e exibi-los agora mostrará seu estado atual (já alterado). Se você clicar em
+
, deverá ver abar
propriedade em seu exemplo.Aqui está uma captura de tela que foi postada no relatório de bug para explicar sua "correção":
Portanto, alguns valores podem ser referenciados muito tempo depois de terem sido registrados, e a avaliação deles é bastante lenta ("quando necessário"). O exemplo mais famoso dessa discrepância é tratado na pergunta O console JavaScript do Chrome tem preguiça de avaliar arrays?
Uma solução alternativa é certificar-se de registrar instantâneos serializados de seus objetos sempre, por exemplo, fazendo
console.log(JSON.stringify(obj))
. No entanto, isso funcionará apenas para objetos não circulares e pequenos. Veja também Como posso alterar o comportamento padrão do console.log no Safari? .A melhor solução é usar pontos de interrupção para depuração, onde a execução para completamente e você pode inspecionar os valores atuais em cada ponto. Use o registro apenas com dados serializáveis e imutáveis.
fonte
console.log
ainda é assíncrono no Chrome, pois tinha 8 anos (consulte stackoverflow.com/questions/7389069/… ), a única coisa que muda é que agora o Chrome emite um instantâneo do objeto de referência no vez que você chamaconsole.log
(se você expandir o objeto logado, verá suas propriedades e valores finais após as operações de mutação feitas depoisconsole.log
), ou éconsole.log
realmente síncrono?JSON.parse(JSON.stringify(obj))
como também mencionado no comentário aqui, você obterá um instantâneo na forma de objeto, em vez de uma string.Esta não é realmente uma resposta para a pergunta, mas pode ser útil para alguém que tropeçou nesta postagem e era muito longo para colocar um comentário:
window.console.logSync = (...args) => { try { args = args.map((arg) => JSON.parse(JSON.stringify(arg))); console.log(...args); } catch (error) { console.log('Error trying to console.logSync()', ...args); } };
Isso cria uma versão pseudo-síncrona de
console.log
, mas com as mesmas ressalvas mencionadas na resposta aceita.Uma vez que parece que, no momento, a maioria dos navegadores
console.log
são assíncronos de alguma maneira, você pode querer usar uma função como esta em certos cenários.fonte
Ao usar console.log:
a = {}; a.a=1;console.log(a);a.b=function(){}; // without b a = {}; a.a=1;a.a1=1;a.a2=1;a.a3=1;a.a4=1;a.a5=1;a.a6=1;a.a7=1;a.a8=1;console.log(a);a.b=function(){}; // with b, maybe a = {}; a.a=function(){};console.log(a);a.b=function(){}; // with b
na primeira situação, o objeto é simples o suficiente, então o console pode 'stringificar' e então apresentá-lo a você; mas nas outras situações, a é muito 'complicado' para 'stringify', então o console mostrará o objeto na memória, e sim, quando você olhar para ele, b já estará anexado a a.
fonte