2015-03-29 15 views
5

Ecco il mio codice:Node.js scrittura di file in loop non a caso

function aCallbackInLoop(dataArray) { 
     dataArray.forEach(function (item, index) { 

      fs.appendFile(fileName, JSON.stringify(item) + "\r\n", function (err) { 
       if (err) { 
        console.log('Error writing data ' + err); 
       } else { 
        console.log('Data written'); 
       } 
      }); 
     }); 
    } 

ottengo errori casuali:

Data written 
Data written 
. 
. 
Error writing data Error: UNKNOWN, open 'output/mydata.json' 
Error writing data Error: UNKNOWN, open 'output/mydata.json' 
. 
. 
Data written 
Error writing data Error: UNKNOWN, open 'output/mydata.json' 

La funzione (aCallbackInLoop) è un callback per una richiesta di web-service , che restituisce blocchi di dati in dataArray. Più richieste di servizi Web vengono fatte in un ciclo, quindi questa richiamata viene forse chiamata in parallelo. Dubito che si tratti di un problema di blocco dei file, ma non sono sicuro di come risolvere.

PS: ho fatto in modo che non è un problema di dati (sto registrare tutte le voci dataArray)

Edit: Codice dopo aver provato flusso di scrittura:

function writeDataToFile(fileName, data) { 
    try { 
     var wStream = fs.createWriteStream(fileName); 
     wStream.write(JSON.stringify(data) + "\r\n"); 
     wStream.end(); 
    } catch (err) { 
     console.log(err.message); 
    } 
} 

function aCallbackInLoop(dataArray){ 
    dataArray.forEach(function(item, index){ 
     writeDataToFile(filename, item); //filename is global var 
    }); 
} 

risposta

2

Prova utilizzando la versione sincrona di appendFile - https://nodejs.org/api/fs.html#fs_fs_appendfilesync_filename_data_options

+0

Questo risolve il problema, ma sto ancora sperando di ottenere il modo asincrono di lavorare. In caso contrario, segnerò questa risposta come soluzione. – SlowAndSteady

+1

L'uso di una versione sincrona è raramente la strada giusta da percorrere in un server node.js. – jfriend00

+0

@ jfriend00 - Vero, ma con il contesto dato di scrivere sullo stesso file ancora e ancora, la sincronizzazione è l'approccio migliore. OP potrebbe dover ridisegnare. – manojlds

6

Come è stato osservato, più chiamate appendFile non sono in grado di procedere a causa delle precedenti chiamate appendFile. In questo caso particolare, sarebbe meglio creare un write stream.

var wstream = fs.createWriteStream(fileName); 

dataArray.forEach(function (item) { 
    wstream.write(JSON.stringify(item + "\r\n"); 
}); 

wstream.end(); 

Se volete sapere quando tutti i dati vengono scritti, quindi è possibile registrare una funzione con l'evento finish, come questo

var wstream = fs.createWriteStream(fileName); 

wstream.on("finish", function() { 
    // Writing to the file is actually complete. 
}); 

dataArray.forEach(function (item) { 
    wstream.write(JSON.stringify(item + "\r\n"); 
}); 

wstream.end(); 
+0

Vedo che questa è la strada giusta da percorrere, ma sto ancora ricevendo l'errore. Se utilizzo appendFileSync, allora tutto funziona. Ma non voglio usare la versione sincrona. Mi chiedo ancora cosa sto sbagliando! – SlowAndSteady

+0

@SlowAndSteady Puoi mostrare il codice effettivo che hai provato? – thefourtheye

+0

@SlowAndSteady Perché stai creando uno stream per ogni dato? Meglio cambiarlo come nel modo in cui ho mostrato (crea stream solo una volta) e prova. – thefourtheye