Array forEach, kolejność przetwarzania, zapis do pliku

0

Aloha

Zgodnie z dokumentacją forEach, tablica przetwarzana jest wg kolejności indeksów. Mam mniej więcej taki kod:

var file = fs.openSync(dest, 'w');
myArray.forEach(m => fs.write(file, m.date));

i w pliku wynikowym daty nie są po kolei (w tablicy są). Są "mniej więcej" po kolei, ale np. 3..5 ostatnich wpisów jest gdzieś ze środka. Obwiniałem forEach, ale chyba niepotrzebnie, bo jak dodałem tam console.info() to wpisy mam w kolejności prawidłowej, więc podejrzenie padło na fs.write(). Jakoś nigdy wcześniej nie pisałem w JS do pliku, może ten sposób jest błędny? Można to zrobić lepiej?

2

Dzieje się tak, poniewaź fs.write jest asynchroniczne, więc nie gwarantuje zachowania kolejności. Masz przynajmniej kilka opcji:

  • użyć fs.writeSync - słaby pomysł bo blokujesz apkę na czas zapisu, ale styknie jak to jakiś skrypt, krótsza wersja:
const fs = require('fs')

const data = [
  { date: '1' },
  { date: '2' },
  { date: '3' },
]

data.forEach(item => fs.appendFileSync('myFile', item.date + '\n'))
  • zamiast forEach pobawić się w rekurencyjne wywołania w callbackach,

  • zapisać całość wcześniej przygotowanych danych - proste rozwiązanie, gdy danych nie jest dużo:

const fs = require('fs')

const data = [
  { date: '1' },
  { date: '2' },
  { date: '3' },
]

fs.writeFile('myFile', data.map(item => item.date).join('\n'))
  • użyć streamu - wtedy nic nie blokujesz a zapisy są kolejkowane i nic się nie pomiesza:
const fs = require('fs')

const data = [
  { date: '1' },
  { date: '2' },
  { date: '3' },
]

const datesStream = fs.createWriteStream('myFile', { flags: 'a' })

data.forEach(item => datesStream.write( item.date + '\n'))
0

Dzięki za odpowiedź. Na początku miałem właśnie createWriteStream, ale coś mi zapis nie szedł, więc zmieniłem na file. Teraz widzę, że miałem banalny błąd. Teraz na strumieniu śmiga jak trzeba, dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1