Ich lese gerade Async Javascript von Trevor Burnham. Dies war bisher ein großartiges Buch.
Er spricht davon, dass dieses Snippet und console.log in der Safari- und Chrome-Konsole "asynchron" sind. Leider kann ich das nicht replizieren. Hier ist der Code:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
Wenn dies asynchron wäre, würde ich davon ausgehen, dass das Ergebnis das Buchergebnis ist. console.log () wird in die Ereigniswarteschlange gestellt, bis der gesamte Code ausgeführt wird. Anschließend wird es ausgeführt und verfügt über die Eigenschaft bar.
Es wird angezeigt, obwohl es synchron ausgeführt wird.
Führe ich diesen Code falsch aus? Ist console.log tatsächlich asynchron?
javascript
asynchronous
Hallo Welt
quelle
quelle
console.log()
zeigt das nicht immer den vorherigen Wert an. Die Umgehung, wenn Ihnen dies passiert, besteht darin, alles, was Sie versuchen,console.log()
in eine Zeichenfolge zu konvertieren, die unveränderlich ist, sodass dieses Problem nicht auftritt. Aus Erfahrungconsole.log()
gibt es also einige asynchrone Probleme, die wahrscheinlich mit dem Sammeln von Daten über Prozessgrenzen hinweg zusammenhängen. Dies ist nicht das beabsichtigte Verhalten, sondern ein Nebeneffekt derconsole.log()
internen Funktionsweise (ich persönlich würde es als Fehler betrachten).Antworten:
console.log
ist nicht standardisiert, daher ist das Verhalten eher undefiniert und kann leicht von Release zu Release der Entwicklertools geändert werden. Ihr Buch ist wahrscheinlich veraltet, ebenso wie meine baldige Antwort.Für unseren Code macht es keinen Unterschied, ob er
console.log
asynchron ist oder nicht, er bietet keinerlei Rückruf oder so; und die Werte, die Sie übergeben, werden immer zum Zeitpunkt des Aufrufs der Funktion referenziert und berechnet.Wir wissen nicht wirklich, was dann passiert (OK, wir könnten, da Firebug, Chrome Devtools und Opera Dragonfly alle Open Source sind). Die Konsole muss die protokollierten Werte irgendwo speichern und zeigt sie auf dem Bildschirm an. Das Rendern wird mit Sicherheit asynchron erfolgen (gedrosselt, um Aktualisierungen mit Ratenbegrenzung durchzuführen), ebenso wie zukünftige Interaktionen mit den protokollierten Objekten in der Konsole (wie das Erweitern von Objekteigenschaften).
Die Konsole kann also entweder die veränderlichen Objekte, die Sie protokolliert haben, klonen (serialisieren) oder Verweise darauf speichern. Der erste funktioniert nicht gut mit tiefen / großen Objekten. Zumindest beim ersten Rendern in der Konsole wird wahrscheinlich der "aktuelle" Status des Objekts angezeigt, dh der, als es protokolliert wurde - in Ihrem Beispiel sehen Sie
Object {}
.Wenn Sie das Objekt jedoch erweitern, um seine Eigenschaften weiter zu untersuchen, hat die Konsole wahrscheinlich nur einen Verweis auf Ihr Objekt und seine Eigenschaften gespeichert. Wenn Sie diese jetzt anzeigen, wird der aktuelle (bereits mutierte) Status angezeigt. Wenn Sie auf klicken
+
, sollte diebar
Eigenschaft in Ihrem Beispiel angezeigt werden.Hier ist ein Screenshot, der im Fehlerbericht veröffentlicht wurde , um deren "Fix" zu erklären:
Daher werden einige Werte möglicherweise lange nach der Protokollierung referenziert, und die Auswertung dieser Werte ist eher träge ("bei Bedarf"). Das bekannteste Beispiel für diese Diskrepanz ist die Frage, ob die JavaScript-Konsole von Chrome bei der Bewertung von Arrays faul ist.
Eine Problemumgehung besteht darin, sicherzustellen, dass serialisierte Snapshots Ihrer Objekte immer protokolliert werden, z
console.log(JSON.stringify(obj))
. Dies funktioniert jedoch nur für nicht kreisförmige und eher kleine Objekte. Siehe auch Wie kann ich das Standardverhalten von console.log in Safari ändern? .Die bessere Lösung besteht darin, Haltepunkte für das Debuggen zu verwenden, bei denen die Ausführung vollständig gestoppt wird und Sie die aktuellen Werte an jedem Punkt überprüfen können. Verwenden Sie die Protokollierung nur mit serialisierbaren und unveränderlichen Daten.
quelle
console.log
in Chrome immer noch asynchron ist, da es 8 Jahre alt war (siehe stackoverflow.com/questions/7389069/… ). Das einzige, was sich ändert, ist, dass Chrome jetzt eine Momentaufnahme des Referenzobjekts am ausgibtconsole.log
Wenn Sie aufrufen (wenn Sie das protokollierte Objekt erweitern, werden seine endgültigen Eigenschaften und Werte nach den Mutationsoperationen angezeigt, nach denen Sie ausgeführt habenconsole.log
) oder ist esconsole.log
tatsächlich synchron?JSON.parse(JSON.stringify(obj))
wie im Kommentar hier erwähnt verwenden, erhalten Sie anstelle einer Zeichenfolge einen Schnappschuss in Objektform.Dies ist keine wirkliche Antwort auf die Frage, aber es könnte für jemanden nützlich sein, der über diesen Beitrag gestolpert ist, und es war zu lang, um einen Kommentar abzugeben:
Dies erzeugt eine pseudosynchrone Version von
console.log
, jedoch mit den gleichen Einschränkungen wie in der akzeptierten Antwort erwähnt.Da es derzeit so aussieht, als ob die meisten Browser
console.log
in irgendeiner Weise asynchron sind, möchten Sie in bestimmten Szenarien möglicherweise eine solche Funktion verwenden.quelle
Bei Verwendung von console.log:
In der ersten Situation ist das Objekt einfach genug, sodass die Konsole es "stringifizieren" und dann für Sie präsentieren kann. In anderen Situationen ist a jedoch zu "kompliziert", um es zu "stringifizieren", sodass die Konsole stattdessen das In-Memory-Objekt anzeigt. Ja, wenn Sie es betrachten, ist b bereits an a angehängt.
quelle