title: FS writeFile(Sync) causing ws.broadcast to not work
body: <p>I was trying to learn the <code>WebSocket</code> API by writing a simple chat application in NodeJS. I needed to save the messages in a file called <code>messages.json</code> that would look something like this:</p>
  <pre class="lang-json prettyprint-override"><code>[
    [
      &quot;username&quot;,
      &quot;message&quot;
    ],
    [
      &quot;username&quot;,
      &quot;message&quot;
    ],
    ...
  ]
  </code></pre>
  <p>I had already completed the client part of it. The HTML and Javascript files looked like this:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;Stuff&lt;/title&gt;
      &lt;link href=&quot;style.css&quot; rel=&quot;stylesheet&quot; /&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;input id=&quot;chatText&quot; placeholder=&quot;Message&quot; /&gt;
      &lt;button
        id=&quot;sendBtn&quot;
        onclick='if (document.getElementById(&quot;chatText&quot;).value.trim() !== &quot;&quot;) ws.send(document.getElementById(&quot;chatText&quot;).value + &quot; &quot; + user); document.getElementById(&quot;chatText&quot;).value = &quot;&quot;'
      &gt;
        &lt;span style=&quot;margin-left: 5px&quot;&gt;&lt;/span&gt;Send&lt;span
          style=&quot;margin-left: 5px&quot;
        &gt;&lt;/span&gt;
      &lt;/button&gt;
      &lt;br /&gt;
      &lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <pre class="lang-js prettyprint-override"><code>var user = prompt('Username?').trim()
  
  while (user.split(' ').length &gt; 1 || user.trim() === '') {
    user = prompt('Username?').trim()
  }
  
  var ws = new WebSocket(&quot;ws://localhost:8080&quot;);
  
  ws.onopen = function (event) {
    console.log('Connection successfully opened!');
  };
  
  ws.onerror = function (err) {
    console.log('err: ', err);
  }
  
  ws.onmessage = function (event) {
    var div = document.createElement('div')
    div.classList.add('chatMsg')
    div.innerText = event.data.split(/ (?=[^ ]+$)/)[1] + ': ' + event.data.split(/ (?=[^ ]+$)/)[0]
    document.body.appendChild(div)
  };
  </code></pre>
  <p>I used a regex to split the data at the last space character, because I found out that I couldn't send an array or an object from the client to the server or vice versa, and the username couldn't contain any spaces, although I might have been overcomplicating things accidentally.</p>
  <p>Then, the server-side NodeJS code had to be written. I completed it as far as this when I wanted to save the messages permanently:</p>
  <pre class="lang-js prettyprint-override"><code>const express = require('express');
  const bodyParser = require('body-parser');
  const app = express();
  
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));
  
  app.use(express.static('public'));
  
  app.get('/', (req, res) =&gt; {
    res.sendFile('public/index.html');
  });
  
  app.listen(8000, () =&gt; console.log('server started'));
  
  const WebSocketServer = require('ws').Server
  const wss = new WebSocketServer({ port: 8080 });
  
  wss.on('connection', ((ws) =&gt; {
    ws.on('message', (message) =&gt; {
      wss.broadcast(message);
    });
  
    ws.on('end', () =&gt; {
      console.log('Connection ended...');
    });
  }));
  
  wss.broadcast = function broadcast(msg) {
    wss.clients.forEach(function each(client) {
      client.send(msg);
    });
  };
  </code></pre>
  <p>So far, I was able to send messages from one browser tab, and the other tab was able to receive them correctly and send another message, and so on. I thought that the best way to save the messages permanently would be a JSON file, so I created  a file named <code>messages.json</code>, which was mentioned above.</p>
  <p>At the start of the program, I read the file by including <code>var messages = require('./messages.json')</code> and <code>require</code>d the module <code>fs</code> to write to <code>messages.json</code>.</p>
  <pre class="lang-js prettyprint-override"><code>const fs = require('fs');
  const messages = require('./messages.json');
  </code></pre>
  <p>I then changed <code>ws.on('message', (message) =&gt; { ...</code> to look like the following:</p>
  <pre class="lang-js prettyprint-override"><code>ws.on('message', (message) =&gt; {
    messages.push(message.split(/ (?=[^ ]+$)/))
    fs.writeFile('./messages.json', JSON.stringify(messages), () =&gt; { })
    wss.broadcast(message);
  });
  </code></pre>
  <p>Then, I opened two tabs in my browser at <code>file:// ... /public/index.html</code>. I sent a message from the first tab. I then switched to the second tab and tried to send a message. I typed something into the input and pressed the &quot;Send&quot; button, and the text inside the input disappeared like it was supposed to, but nothing else happened. I then switched back to the first tab and tried the same thing, but it behaved the same way as the second tab did. I switched back to the VSCode window and checked the terminal, but there were no errors. I opened <code>messages.json</code> and saw only one message inside the array. The file looked like this:</p>
  <pre class="lang-json prettyprint-override"><code>[
    [
      &quot;user&quot;,
      &quot;test&quot;
    ]
  ]
  </code></pre>
  <p>I was confused, because I had sent three messages, but only one had been recorded inside the file. I reset <code>messages.json</code> to <code>[]</code> and used <code>fs.readFileSync</code> instead of <code>fs.readFile</code>. Nothing changed, Then, for debugging purposes, I changed the line <code>fs.writeFile('./messages.json', JSON.stringify(messages), () =&gt; { })</code> to <code>console.log('test')</code>. I closed both the tabs and opened them again. Then, I sent a message from the first tab, one from the second, and another one from the first tab. Everything worked like it was supposed to, and both tabs showed the messages. The terminal showed the output:</p>
  <pre class="lang-none prettyprint-override"><code>test
  test
  test
  </code></pre>
  <p>It was working as expected. Why is it not working with <code>fs.readFile</code> and <code>fs.readFileSync</code>?</p>
  <p>To run and reload the server, I am using an NPM script named <code>live</code> with <code>nodemon</code>:</p>
  <pre class="lang-json prettyprint-override"><code>&quot;scripts&quot;: {
    &quot;live&quot;: &quot;nodemon index.js&quot;
  },
  </code></pre>
  <p>To start the server, I just simply ran <code>nodemon index.js</code> in the terminal.</p>
  <p>My directory structure:</p>
  <pre class="lang-none prettyprint-override"><code>node_modules
  public
    |-- index.html
    |-- script.js
  index.js
  messages.json
  package.json
  </code></pre>