Rolf B: javascript race condition

Beitrag lesen

Hallo Pit,

die anderen Antworten haben sich auf externe race-conditions bezogen, also Konkurrenz mit anderen Instanzen deines Programms. Ich habe noch eine andere.

JavaScript ist single-threaded, solange Du keine Webworker einsetzt und keine Requeste auf externe Dienste machst. Innerhalb deines JS wirst Du keine race condition erhalten.

Dein Callback, in dem Du den push machst, läuft ab nachdem die Daten von readJson empfangen wurden.

Problematisch ist dagegen dein writeJson, weil das außerhalb des readJson Callbacks läuft. D.h. dein Programm setzt den readJson Request ab, der registriert unter der Haube einen Handler, der auf die empfangenen Daten reagiert. UND DANN IST readJson ZU ENDE!

D.h. der writeJson Aufruf läuft, während noch auf den Empfang von readJson gewartet wird. Eine Variable data gibt es jetzt gar nicht. Falls Du sie global definiert hättest, wäre sie jetzt noch undefined. Und das ist ein race, den Du nur verlieren kannst. Du solltest ggf. mit dem Promise arbeiten, das von readJson zurückgegeben wird, dann kann man das schön verketten:

const nlFile2 = './data/file.json';
fs.readJson(nlFile2)
.then(data => {
  data.push({
    email: req.body.mail,
    name: req.body.Name
  });
  return fs.writeJson('./data/file.json', data);
})
.then(() => {
  console.log('success!')
})
.catch(err => {
  console.error(err)
});

Wenn ein .then Handler ein Promise zurückgibt, wartet ein nachgelagerter .then Handler auf die Erfüllung dieses Promise. Dadurch wird dein 'success' erst ausgegeben, wenn der Write fertig ist.

Wichtig ist jedenfalls, dass writeJson von der erfolgreichen Ausführung von readJson abhängig ist, und das geht nur wenn es in einem Callback steht. Entweder direkt, oder über ein Promise gekapselt.

Rolf

--
sumpsi - posui - clusi