Je lis actuellement Async Javascript par Trevor Burnham. Cela a été un excellent livre jusqu'à présent.
Il dit que cet extrait et console.log sont «asynchrones» dans la console Safari et Chrome. Malheureusement, je ne peux pas reproduire cela. Voici le code:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
Si c'était asynchrone, j'anticiperais que le résultat serait celui des livres. console.log () est placé dans la file d'attente des événements jusqu'à ce que tout le code soit exécuté, puis il est exécuté et il aurait la propriété bar.
Il semble bien qu'il fonctionne de manière synchrone.
Est-ce que j'exécute mal ce code? Console.log est-il réellement asynchrone?
javascript
asynchronous
Bonjour le monde
la source
la source
console.log()
n'affiche pas toujours l'ancienne valeur. La solution de contournement si cela vous arrive est de convertir tout ce que vous essayez deconsole.log()
faire en une chaîne immuable, donc non sujette à ce problème. Ainsi, par expérience,console.log()
certains problèmes asynchrones sont probablement liés au marshaling des données au-delà des limites du processus. Ce n'est pas le comportement prévu, mais c'est un effet secondaire de la façon dontconsole.log()
fonctionne en interne (je le considérerais personnellement comme un bogue).Réponses:
console.log
n'est pas standardisé, donc le comportement est plutôt indéfini et peut être changé facilement d'une version à l'autre des outils de développement. Votre livre sera probablement obsolète, comme ma réponse pourrait bientôt.Pour notre code, cela ne fait aucune différence que ce
console.log
soit asynchrone ou non, cela ne fournit aucun type de rappel ou autre; et les valeurs que vous transmettez sont toujours référencées et calculées au moment où vous appelez la fonction.Nous ne savons pas vraiment ce qui se passe alors (OK, nous pourrions, puisque Firebug, Chrome Devtools et Opera Dragonfly sont tous open source). La console devra stocker les valeurs enregistrées quelque part et les affichera à l'écran. Le rendu se produira de manière asynchrone à coup sûr (étant limité aux mises à jour de limite de débit), tout comme les interactions futures avec les objets journalisés dans la console (comme l'expansion des propriétés d'objet).
Ainsi, la console peut soit cloner (sérialiser) les objets mutables que vous avez consignés, soit stocker des références à ceux-ci. Le premier ne fonctionne pas bien avec les objets profonds / grands. De plus, au moins le rendu initial dans la console montrera probablement l'état "actuel" de l'objet, c'est-à-dire celui lorsqu'il a été connecté - dans votre exemple que vous voyez
Object {}
.Cependant, lorsque vous développez l'objet pour inspecter davantage ses propriétés, il est probable que la console aura uniquement stocké une référence à votre objet et à ses propriétés, et les afficher maintenant affichera alors leur état actuel (déjà muté). Si vous cliquez sur
+
, vous devriez pouvoir voir labar
propriété dans votre exemple.Voici une capture d'écran qui a été publiée dans le rapport de bogue pour expliquer leur «correctif»:
Ainsi, certaines valeurs peuvent être référencées longtemps après avoir été consignées, et leur évaluation est plutôt paresseuse («si nécessaire»). L'exemple le plus célèbre de cet écart est traité dans la question La console JavaScript de Chrome est-elle paresseuse pour évaluer les tableaux?
Une solution de contournement consiste à vous assurer de toujours consigner les instantanés sérialisés de vos objets, par exemple en faisant
console.log(JSON.stringify(obj))
. Cela fonctionnera uniquement pour les objets non circulaires et plutôt petits. Voir aussi Comment puis-je changer le comportement par défaut de console.log dans Safari? .La meilleure solution consiste à utiliser des points d'arrêt pour le débogage, où l'exécution s'arrête complètement et vous pouvez inspecter les valeurs actuelles à chaque point. Utilisez la journalisation uniquement avec des données sérialisables et immuables.
la source
console.log
est toujours asynchrone dans Chrome car il avait 8 ans (voir stackoverflow.com/questions/7389069/… ), la seule chose qui change est que maintenant Chrome produit un instantané de l'objet de référence au l'heure à laquelle vous appelezconsole.log
(si vous développez l'objet journalisé, vous verrez ses propriétés et valeurs finales après les opérations de mutation que vous avez effectuées aprèsconsole.log
), ou est-il enconsole.log
effet synchrone?JSON.parse(JSON.stringify(obj))
comme mentionné dans le commentaire ici, vous obtenez un instantané sous forme d'objet, au lieu d'une chaîne.Ce n'est pas vraiment une réponse à la question, mais cela pourrait être pratique pour quelqu'un qui est tombé sur ce post, et c'était trop long pour mettre un commentaire:
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); } };
Cela crée une version pseudo-synchrone de
console.log
, mais avec les mêmes mises en garde que celles mentionnées dans la réponse acceptée.Puisqu'il semble que, pour le moment, la plupart des navigateurs
console.log
soient asynchrones d'une certaine manière, vous voudrez peut-être utiliser une fonction comme celle-ci dans certains scénarios.la source
Lors de l'utilisation de 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
dans la première situation, l'objet est assez simple, donc la console peut le «stringifier» puis vous le présenter; mais dans les autres situations, a est trop «compliqué» pour «stringifier», donc la console vous montrera l'objet en mémoire à la place, et oui, quand vous le regardez, b est déjà attaché à a.
la source