console.log () asynchronous ou sincronizado?

Atualmente estou lendo o Javascript Async por Trevor Burnham. Este tem sido um ótimo livro até agora.

Ele fala sobre este snippet e console.log sendo ‘asynchronous‘ no console do 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 asynchronous, eu anteciparia que o resultado seria o resultado dos livros. O console.log () é colocado na fila de events 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 asynchronous?

console.log não é padronizado, portanto, o comportamento é bastante indefinido e pode ser alterado facilmente de um release para outro das ferramentas do desenvolvedor. Seu livro provavelmente está desatualizado, assim como minha resposta em breve.

Para o nosso código, não faz diferença se o console.log é asynchronous ou não, ele 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 function.

Nós realmente não sabemos o que acontece então (OK, poderíamos, já que o Firebug, o Chrome Devtools e o Opera Dragonfly são todos de código aberto). O console precisará armazenar os valores registrados em algum lugar e os exibirá na canvas. A renderização ocorrerá de forma assíncrona, com certeza (sendo acelerada para atualizações de limite de taxa), assim como futuras interações com os objects registrados no console (como propriedades de object em expansão).

Portanto, o console pode clonar (serializar) os objects mutáveis ​​que você registrou ou armazenar referências a eles. O primeiro não funciona bem com objects profundos. Além disso, pelo menos a renderização inicial no console provavelmente mostrará o estado “atual” do object, ou seja, aquele quando ele foi registrado – no seu exemplo você vê o Object {} .

No entanto, quando você expande o object para inspecionar ainda mais suas propriedades, é provável que o console tenha armazenado apenas uma referência ao seu object e suas propriedades, e exibi-las agora mostrará seu estado atual (já mutado). Se você clicar no sinal + , poderá ver a propriedade da bar no seu exemplo.

Aqui está uma captura de canvas que foi publicada no relatório de erros para explicar sua “correção”:

Assim, alguns valores podem ser referenciados por muito tempo depois de terem sido registrados, e a avaliação destes é bastante preguiçosa (“quando necessário”). O exemplo mais famoso dessa discrepância é tratado na pergunta : O console JavaScript do Chrome é preguiçoso na avaliação de matrizes? Uma solução é certificar-se de logar instantâneos serializados de seus objects sempre, por exemplo, fazendo console.log(JSON.stringify(obj)) . Isso funcionará apenas para objects não circulares e pequenos. Veja também Como posso alterar o comportamento padrão de console.log? (* Console de erro no safari, sem complemento *) .

Ao usar o console.log:

 a = {}; aa=1;console.log(a);ab=function(){}; // without b a = {}; aa=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);ab=function(){}; // with b, maybe a = {}; aa=function(){};console.log(a);ab=function(){}; // with b 

na primeira situação, o object é simples o suficiente, de modo que o console pode ‘estigmatizá-lo’ e apresentá-lo a você; mas nas outras situações, a é muito “complicado” para “stringify”, então o console mostrará o object in memory, e sim, quando você olhar para ele, b já estará conectado a um object.