The asynchronous method of file writing puts a write request on the event queue and then returns control back to the calling code. The actual write does not take place until the event loop picks up the write request and executes it. You need to be careful when performing multiple asynchronous write requests on the same file because you cannot guarantee the execution order unless you wait for the first write callback before executing the next one. Typically the simplest way to do this is to nest writes inside the callback from the previous write. The code in Listing 6.3 illustrates this process.
To write to a file asynchronously, first open it using open()
and then after the callback from the open request has executed, use fs.write()
to write data to the file. The following is the syntax for fs.write()
:
fs.write(fd, data, offset, length, position, callback)
The fd
parameter is the file descriptor that openSync()
returns. The data
parameter specifies the String
or Buffer
object that will be written to the file. The offset
parameter specifies the index in the input data to begin reading data. If you want to begin at the current index in the string or buffer, this value should be null
. The length
parameter specifies the number of bytes to write; if you want to write at the end of the buffer, specify null
for this parameter. The position
argument specifies the position in the file to begin writing. To use the current file position, specify null
for this value.
The callback
argument must be a function that can accept two parameters, error
and bytes
, where error
is an error that occurred during the write and bytes
specifies the number of bytes written.
The code in Listing 6.3 shows how to implement basic asynchronous writing to store a series of string data in a file. Notice that the callback specified in lines 18–20 in the open()
callback calls the writeFruit()
function and passes the file descriptor. Also notice that the write()
callback specified in lines 6–13 also calls writeFruit()
and passes the file descriptor. This ensures that the asynchronous write completes before another executes. Figure 6.3 shows the output of the code in Listing 6.3.
01 var fs = require('fs'),
02 var fruitBowl = ['apple', 'orange', 'banana', 'grapes'];
03 function writeFruit(fd){
04 if (fruitBowl.length){
05 var fruit = fruitBowl.pop() + " ";
06 fs.write(fd, fruit, null, null, function(err, bytes){
07 if (err){
08 console.log("File Write Failed.");
09 } else {
10 console.log("Wrote: %s %dbytes", fruit, bytes);
11 writeFruit(fd);
12 }
13 });
14 } else {
15 fs.close(fd);
16 }
17 }
18 fs.open('../data/fruit.txt', 'w', function(err, fd){
19 writeFruit(fd);
20 });