2017-07-11 35 views
1

我仍在学习nodejs。这个问题与其他一些问题有关(例如,Writing multiple files a loop in Nodejs),但有点不同。其实很简单。我想写一些文件,当它完成后继续执行其他任务。nodejs:在循环中写入多个文件

没有for循环,我做这样的,

fs.readFile(f1.path, function(err, data) { 
    fs.writeFile("/tmp/" + f1.path, data, function(err) { 
     fs.readFile(f2.path, function(err, data) { 
      fs.writeFile("/tmp/" + f2.path, data, function(err) { 
       ... 
       if (err) throw err; 

       // do something when all files are written 

如果我想用for循环转换,怎么办呢?假设我可以将f1,f2 ...放入数组并迭代它们。

谢谢你的帮助。

回答

0

您可以保存承诺在阵列中,并使用Promise.all等待他们全部完成:

const fs = require('fs'); 
const path = require('path'); 

const files = [f1, f2, ...]; 

function copyFile(source, destination) { 
    const input = fs.createReadStream(source); 
    const output = fs.createWriteStream(destination); 
    return new Promise((resolve, reject) => { 

     output.on('error', reject); 
     input.on('error', reject); 
     input.on('end', resolve); 
     input.pipe(output); 
    }); 
} 

const promises = files.map(file => { 
    const source = file.path; 
    const destination = path.join('/tmp', file.path); 
    // Use these instead of line above if you have files in different 
    // directories and want them all at the same level: 
    // const filename = path.parse(file.path).base; 
    // const destination = path.join('/tmp', filename); 
    return copyFile(source, destination); 
}); 

Promise.all(promises).then(_ => { 
    // do what you want 
    console.log('done'); 
}).catch(err => { 
    // handle I/O error 
    console.error(err); 
}); 
+0

运作良好。我会拿起你的答案。非常感谢! – user180574

1

您可以使用递归来在没有其他库的情况下执行此操作。下面的代码将复制Array中的文件,等待前一个文件完成复制,然后再异步移动到下一个文件。

方法使用流使用fs.readFile()fs.writeFile()

const fs = require('fs') 
const path = require('path') 

// your files array 
let files = [f1, f2] 

function copyFile (index, cb) { 
    let file = files[index] 
    let dest = path.join('/tmp', file.path) 
    if (!file) { 
    // done copying 
    return cb(null) 
    } 
    fs.readFile(file.path, (err, data) => { 
    if (err) { 
     // return callback with error 
     return cb(err) 
    } else { 
     fs.writeFile(dest, data, (err) => { 
     if (err) { 
      return cb(err) 
     } else { 
      copyFile(index + 1, cb) 
     } 
     }) 
    } 
    }) 
} 

copyFile(0, (err) => { 
    if (err) { 
     // Handle Error 
     console.log(err) 
    } else { 
     console.log('Files Copied Successfully!') 
    } 
}) 

的做法,在我看来,更好的

const fs = require('fs') 
const path = require('path') 

// your files array 
let files = [f1, f2] 

function copyFile(index, cb) { 
    let file = files[index] 
    let dest = path.join('/tmp', file.path) 

    if (!file) { 
     return cb(null) 
    } 

    let source = fs.createReadStream(file.path) 
    let copy = fs.createWriteStream(dest) 

    source.on('error', err => { 
     // explicitly close writer 
     copy.end() 
     return cb(err) 
    }) 

    copy.on('error', err => { 
     return cb(err) 
    }) 

    copy.on('finish',() => { 
     copyFile(index + 1, cb) 
    }) 

    source.pipe(copy) 
} 

copyFile(0, (err) => { 
    if (err) { 
     // Handle Error 
     console.log(err) 
    } else { 
     console.log('Files Copied Successfully!') 
    } 
}) 
+1

很酷,非常感谢! – user180574

-1
files= []; 

var writeFile = function(fl,next){ 
fs.readFile(f1.path, function(err, data) { 
    fs.writeFile("/tmp/" + f1.path, data, function(err) { 
     writeFile(files[next],next++) 
     }); 
    }); 
}; 
writeFile(files[0],1) 
+1

请将解释添加到您的答案。 –

0

这是另一种方式

const fs = require("fs"); 
    const listOfFiles = [{fileName:"a.txt",data:"dummy data!"},{fileName:"b.txt",data:"dummy data b!"},{fileName:"c.txt",data:"dummy data c!"},{fileName:"d.txt",data:"dummy data d!"},{fileName:"e.txt",data:"dummy data e!"}]; 

    listOfFiles.reduce(function(curFile, nextFile){ 
      return writeData(nextFile).then(); 
    }, writeData); 

    console.log("Another Code to be executed!"); 
    console.log("Another Code to be executed!"); 
    console.log("Another Code to be executed!"); 
    console.log("Another Code to be executed!"); 

    function writeData(params){ 
     return new Promise((resolve,reject)=>{ 
     fs.writeFile(params.fileName,params.data,'utf8',(err)=>{ 
      if(err) 
       reject(err); 
      else 
       resolve(); 
      }); 
    }); 
}