102 votes

Le fichier console.log de node.js est-il asynchrone ?

Sont console.log/debug/warn/error dans node.js asynchrone ? Je veux dire que l'exécution du code javascript s'arrêtera-t-elle jusqu'à ce que le contenu soit imprimé à l'écran ou s'imprimera-t-il plus tard ?

De plus, j'aimerais savoir s'il est possible qu'un console.log n'affiche rien si l'instruction qui suit immédiatement le nœud se plante.

110voto

Ivo Wetzel Points 27802

Mise à jour : À partir de Node 0.6, ce post est obsolète, puisque stdout est synchrone maintenant.

Eh bien, voyons ce que console.log le fait réellement.

Tout d'abord, il fait partie de la module de console :

exports.log = function() {
  process.stdout.write(format.apply(this, arguments) + '\n');
};

Donc il fait simplement un peu de formatage et écrit à process.stdout rien d'asynchrone jusqu'à présent.

process.stdout est un getter défini au démarrage qui est initialisé paresseusement, j'ai ajouté quelques commentaires pour expliquer les choses :

.... code here...
process.__defineGetter__('stdout', function() {
  if (stdout) return stdout;                            // only initialize it once 

  /// many requires here ...

  if (binding.isatty(fd)) {                             // a terminal? great!
    stdout = new tty.WriteStream(fd);
  } else if (binding.isStdoutBlocking()) {              // a file?
    stdout = new fs.WriteStream(null, {fd: fd});
  } else {
    stdout = new net.Stream(fd);                        // a stream? 
                                                        // For example: node foo.js > out.txt
    stdout.readable = false;
  }

  return stdout;
});

Dans le cas d'un TTY et d'UNIX, nous finissons par ici cette chose hérite de socket. Donc tout ce que fait ce noeud est de pousser les données sur le socket, puis le terminal s'occupe du reste.

Testons-le !

var data = '111111111111111111111111111111111111111111111111111';
for(var i = 0, l = 12; i < l; i++) {
    data += data; // warning! gets very large, very quick
}

var start = Date.now();
console.log(data);
console.log('wrote %d bytes in %dms', data.length, Date.now() - start);

Résultat

....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms

real    0m0.969s
user    0m0.068s
sys  0m0.012s

Le terminal a besoin d'environ 1 seconde pour imprimer le contenu des sockets, mais node n'a besoin que de 17 millisecondes pour pousser les données vers le terminal.

Il en va de même pour le cas du flux, et le cas du fichier est également traité. asynchrone .

Alors oui Node.js tient ses promesses de non-blocage.

2 votes

Mise à jour : stdout dans node.js est maintenant synchrone : groups.google.com/group/nodejs/browse_thread/thread/

1 votes

Je pense que c'est obsolète maintenant : github.com/nodejs/node/issues/3524#issuecomment-151097761

0 votes

@IvoWetzel Je vais devoir downvoter ceci maintenant car c'est obsolète.

29voto

Matt Ranney Points 1068

Console.warn() et console.error() sont bloquantes. Elles ne reviennent pas tant que les appels système sous-jacents n'ont pas réussi.

Oui, il est possible qu'un programme se termine avant que tout ce qui a été écrit sur stdout ait été purgé. process.exit() mettra fin au nœud immédiatement, même s'il y a encore des écritures sur stdout en attente. Vous devriez utiliser console.warn pour éviter ce comportement.

1 votes

Ceci n'est pas vrai pour Node 0.10.25 sous Windows. console.warn() y console.error() ont le même comportement non bloquant que console.log() . Il y a même un pour résoudre le problème sous Windows .

13voto

doron aviguy Points 258

Ma conclusion, après avoir lu la documentation de Node.js 10.* (jointe ci-dessous), est que vous pouvez utiliser console.log pour la journalisation, console.log est synchrone et implémenté en bas niveau c . Bien que console.log soit synchrone, il ne posera pas de problème de performance si vous n'enregistrez pas une grande quantité de données.

(L'exemple de ligne de commande ci-dessous démontre, console.log asynchrone et le fichier console.error est sync )

Sur la base de Doc's Node.js

Les fonctions de la console sont synchrones lorsque la destination est un terminal ou un fichier (pour éviter les messages perdus en cas de sortie prématurée) et asynchrones lorsqu'il s'agit d'un pipe (pour éviter de bloquer pendant de longues périodes).

C'est-à-dire que dans l'exemple suivant, stdout est non bloquant alors que stderr est bloquant :

$ node script.js 2> error.log | tee info.log

Dans l'utilisation quotidienne, la dichotomie blocage/non-blocage n'est pas quelque chose dont vous devriez vous soucier, sauf si vous > enregistrez d'énormes quantités de données.

J'espère que cela vous aidera

3voto

Ali Azlan Points 144

Console.log est asynchrone sous Windows alors qu'il est synchrone sous linux/mac. Pour rendre console.log synchrone sous Windows, écrivez cette ligne au début de votre code, probablement dans le fichier index.js. Toute console.log après cette déclaration sera considérée comme synchrone par l'interpréteur.

if (process.stdout._handle) process.stdout._handle.setBlocking(true);

1voto

Berty Points 171

Vous pouvez l'utiliser pour la journalisation synchrone :

const fs = require('fs')
fs.writeSync(1, 'Sync logging\n')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X