Actualmente estoy leyendo Async Javascript de Trevor Burnham. Este ha sido un gran libro hasta ahora.
Habla de que este fragmento y console.log son 'async' en la consola de Safari y Chrome. Desafortunadamente, no puedo replicar esto. Aquí está el código:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
Si esto fuera asincrónico, anticiparía que el resultado será el resultado de los libros. console.log () se coloca en la cola de eventos hasta que se ejecute todo el código, luego se ejecuta y tendría la propiedad bar.
Parece que se está ejecutando sincrónicamente.
¿Estoy ejecutando mal este código? ¿Console.log es realmente asincrónico?
javascript
asynchronous
Hola Mundo
fuente
fuente
console.log()
no siempre muestra el valor anterior. La solución si esto le sucede a usted es convertir todo lo que esté intentandoconsole.log()
en una cadena que sea inmutable, por lo que no está sujeta a este problema. Por lo tanto, según la experiencia,console.log()
tiene algunos problemas de asincronía probablemente relacionados con la clasificación de datos a través de los límites del proceso. Este no es el comportamiento previsto, pero es un efecto secundario de cómoconsole.log()
funciona internamente (personalmente lo consideraría un error).Respuestas:
console.log
no está estandarizado, por lo que el comportamiento es bastante indefinido y se puede cambiar fácilmente de una versión a otra de las herramientas de desarrollo. Es probable que su libro esté desactualizado, al igual que mi respuesta pronto.Para nuestro código, no importa si
console.log
es asíncrono o no, no proporciona ningún tipo de devolución de llamada; y los valores que pasa siempre se referencian y calculan en el momento en que llama a la función.Realmente no sabemos qué sucede entonces (de acuerdo, podríamos, ya que Firebug, Chrome Devtools y Opera Dragonfly son todos de código abierto). La consola necesitará almacenar los valores registrados en algún lugar y los mostrará en la pantalla. La renderización ocurrirá de forma asincrónica con seguridad (se limitará a actualizaciones de límite de velocidad), al igual que las interacciones futuras con los objetos registrados en la consola (como expandir las propiedades del objeto).
Entonces, la consola podría clonar (serializar) los objetos mutables que registró, o almacenará referencias a ellos. El primero no funciona bien con objetos grandes o profundos. Además, al menos la representación inicial en la consola probablemente mostrará el estado "actual" del objeto, es decir, el que se registró en el ejemplo que ve
Object {}
.Sin embargo, cuando expande el objeto para inspeccionar más sus propiedades, es probable que la consola solo haya almacenado una referencia a su objeto y sus propiedades, y mostrarlos ahora mostrará su estado actual (ya mutado). Si hace clic en
+
, debería poder ver labar
propiedad en su ejemplo.Aquí hay una captura de pantalla que se publicó en el informe de errores para explicar su "solución":
Por lo tanto, es posible que se haga referencia a algunos valores mucho después de que se hayan registrado, y la evaluación de estos es bastante lenta ("cuando sea necesario"). El ejemplo más famoso de esta discrepancia se maneja en la pregunta ¿La consola JavaScript de Chrome es perezosa para evaluar matrices?
Una solución alternativa es asegurarse de registrar instantáneas serializadas de sus objetos siempre, por ejemplo, haciendo
console.log(JSON.stringify(obj))
. Sin embargo, esto funcionará solo para objetos no circulares y bastante pequeños. Consulte también ¿Cómo puedo cambiar el comportamiento predeterminado de console.log en Safari? .La mejor solución es utilizar puntos de interrupción para la depuración, donde la ejecución se detiene por completo y puede inspeccionar los valores actuales en cada punto. Utilice el registro solo con datos seriales e inmutables.
fuente
console.log
todavía es asíncrono en Chrome ya que tenía 8 años (consulte stackoverflow.com/questions/7389069/… ), lo único que cambia es que ahora Chrome genera una instantánea del objeto de referencia en el hora a la que llamaconsole.log
(si expande el objeto registrado, verá sus propiedades y valores finales después de las operaciones de mutación que realizó despuésconsole.log
), o esconsole.log
sincrónicoJSON.parse(JSON.stringify(obj))
como también se menciona en el comentario aquí , obtendrá una instantánea en forma de objeto, en lugar de una cadena.Esta no es realmente una respuesta a la pregunta, pero podría ser útil para alguien que tropezó con esta publicación y fue demasiado largo para poner un comentario:
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); } };
Esto crea una versión pseudo-sincrónica de
console.log
, pero con las mismas advertencias que se mencionan en la respuesta aceptada.Como parece que, en este momento, la mayoría de los navegadores
console.log
son asincrónicos de alguna manera, es posible que desee utilizar una función como esta en ciertos escenarios.fuente
Al 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
en la primera situación, el objeto es lo suficientemente simple, por lo que la consola puede 'encadenarlo' y luego presentárselo; pero en las otras situaciones, a es demasiado 'complicado' para 'encadenar', por lo que la consola le mostrará el objeto en memoria en su lugar, y sí, cuando lo mira, b ya está adjunto a a.
fuente