2015-05-26 59 views
2

什么下面的代码确实是采取了几个文本文件从一个文件夹,并把它们添加到文件:fs.appendFile不按顺序追加数据?

#!/usr/bin/env node 

'use strict' 

const fs = require('fs') 
    , input = process.argv[2] 

if (process.argv.length < 3) { 
    console.log('Usage: node ' + process.argv[1] + ' FILENAME') 
    process.exit(1) 
} 

fs.readdir(__dirname + `/${input}/`, (err, files) => { 
    if (err) { 
    return 
    } 

    files.forEach((file, index) => { 
    fs.readFile(__dirname + `/${input}/` + file, 'utf8', (err, data) => { 
     let result 

     if (err) { 
     console.log(err) 
     } 

     if (index == files.length - 1) { 
     result = `${data}` 
     } else { 
     result = `${data}\n` 
     } 

     fs.appendFile("merged.txt", result, (err) => { 
     if (err) { 
      console.log(err) 
     } else { 
      console.log(result) 
     } 
     }) 
    }) 
    }) 
}) 

所以我们可以说我有一个文件夹,名为docs和内部有doc1.txt,DOC2 txt文件,doc3.txt with the content ##文件1,##文档2,和##文件3 respectively. The code would produce a single file called merged.txt`与内容:

## Doc 1 

## Doc 2 

## Doc 3 

它工作正常。但有时候这个顺序是错误的。我会得到这样的东西:

## Doc 1 

## Doc 3 

## Doc 2 

尤其是当有很多文件。

如何修改代码来防止此问题?

+2

您正在并行运行一堆异步操作。没有保证的执行顺序,除非您手动排序操作以强制执行特定顺序。 – jfriend00

+1

您正在同步调用常规'forEach'内的异步函数('appendFile')。不能保证在调用下一个'appendFile'时,前面的'appendFile'将会完成。看看promise([q](https://www.npmjs.com/package/q)或[bluebird](https://www.npmjs.com/package/bluebird)),甚至是[async] (https://www.npmjs.com/package/async)模块。 –

回答

1

你可以要么改变fs.appendFilefs.appendFileSync(快速和肮脏的,但不是最好的解决方案),或者你可以使用async模块(https://www.npmjs.com/package/async#eachSeries)的eachSeries方法串联运行的事件。

+3

您的第一个建议不一定会奏效,因为'fs.readFile()'仍然是异步的。 – jfriend00

+0

好点,我忽略了这一点。您必须将'fs.readFile'更改为'fs.readFileSync',并将代码调整为不使用回调。 – Greg