我还在学习nodejs。这个问题与其他几个问题有关(例如Writing multiple files a loop in 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 :(得分:3)
您可以在数组中保存承诺,并使用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);
});
答案 1 :(得分:1)
您可以使用递归来执行此操作而无需其他库。下面的代码将从一个数组中复制文件,等待先前的文件完成复制,然后再异步进入下一个文件。
使用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!')
}
})
答案 2 :(得分: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();
});
});
}
答案 3 :(得分:0)
fs-extra
npm i -D fs-extra
文档:https://www.npmjs.com/package/fs-extra
fs.outputFile
const fs = require('fs-extra');
// Async
outputFile(file, data, [options, callback])
// Sync
outputFileSync(file, data, [options])
如果不存在输出目录,则会以递归方式创建它们。
祝你好运...