Javascript 节点上的文件创建问题
我在使用节点生成文件时遇到问题。这些文件显示的顺序不正确,在创建它们的循环完成后,我的自动git提交发生了错误。有人能帮帮我吗!github回购:Javascript 节点上的文件创建问题,javascript,node.js,Javascript,Node.js,我在使用节点生成文件时遇到问题。这些文件显示的顺序不正确,在创建它们的循环完成后,我的自动git提交发生了错误。有人能帮帮我吗!github回购: 您正在循环中使用异步版本的fs.writeFile,这意味着您不知道将数据写入磁盘的顺序,并且循环不会等待该异步函数的每次调用继续 您必须找到一种方法来知道最后一个文件何时被写入。一种方法是使用同步版本的fs.writeFile函数,其方式如下: execute(){ this.init(); for(let i=0; i<1
您正在循环中使用异步版本的
fs.writeFile
,这意味着您不知道将数据写入磁盘的顺序,并且循环不会等待该异步函数的每次调用继续
您必须找到一种方法来知道最后一个文件何时被写入。一种方法是使用同步版本的fs.writeFile
函数,其方式如下:
execute(){
this.init();
for(let i=0; i<10; ++i) {
const file = resolve(this.root, `file${i}.txt`);
try {
fs.writeFileSync(file, 'Hello world');
console.info('CREATE ', file);
if(fs.existsSync(file)) this.add(file);
} catch (err) {
console.error(err);
}
}
this.commit();
}
execute(){
this.init();
for(设i=0;i这两个fs.writeFile
和child\u process.exec
都是异步的,并且您不会等待操作结束,这就是为什么您的代码没有执行您期望的操作
我们可以使用util.promisify
将writeFile
和exec
转换为基于Promise的API,并使用async/wait
以正确的顺序执行操作
const { promisify } = require('util');
const childProcess = require('child_process');
const fs = require('fs');
const writeFile = promisify(fs.readFile);
const exec = promisify(childProcess.exec);
class Generator {
constructor(){
this.root = resolve(__dirname, 'generated');
}
async execute() {
await this.init();
for(let i=0; i < 10; ++i) {
const file = resolve(this.root, `file${i}.txt`);
await writeFile(file, 'Hello world');
// No need to check if it exists, if it wasn't created writeFile rejects
console.info('CREATE ', file);
await this.add(file);
}
return this.commit();
}
init(){
return exec(`mkdir ${this.root} && cd ${this.root} && git init`);
}
add(file){
return exec(`cd ${this.root} && git add ${file}`);
}
commit(){
return exec(`cd ${this.root} && git commit -m "chore: initial commit"`);
}
}
您将按顺序创建并添加文件,然后提交更改。除非指定或指定了同步,否则使用文档表示它是同步的callback@PierreC.OP从未指定他正在使用第三方,因此我假设正在使用childProcess.exec
,他没有理由为一个简单的.exec
。在我的回答中,我声明childProcess.exec
是异步的,确实是。但由于OP没有使用它,所以回答这个问题与此无关。我可以指出的另一点是OP似乎还不太理解回调。在他的代码中引入承诺和wait/async可能太多了(即使这很有趣)他从不说他在使用shelljs库,我可以这样做:const shelljs=require('child\u process'))
,如果信息不在问题中,我假设他使用的是本机API。async/await
比回调容易,所以是的,我不认为这太多,而且比使用Synchronous API要好得多,这就是您正在使用的API。我还修改了wait/async的一个分支。我确实在使用shelljs,因为它连接了我将我的writefile和shelljs.exec包装在util的promisify中,一切都如预期般神奇地工作。非常感谢!
execute(){
this.init();
for(let i=0; i<10; ++i) {
const file = resolve(this.root, `file${i}.txt`);
try {
fs.writeFileSync(file, 'Hello world');
console.info('CREATE ', file);
if(fs.existsSync(file)) this.add(file);
} catch (err) {
console.error(err);
}
}
this.commit();
}
const { promisify } = require('util');
const childProcess = require('child_process');
const fs = require('fs');
const writeFile = promisify(fs.readFile);
const exec = promisify(childProcess.exec);
class Generator {
constructor(){
this.root = resolve(__dirname, 'generated');
}
async execute() {
await this.init();
for(let i=0; i < 10; ++i) {
const file = resolve(this.root, `file${i}.txt`);
await writeFile(file, 'Hello world');
// No need to check if it exists, if it wasn't created writeFile rejects
console.info('CREATE ', file);
await this.add(file);
}
return this.commit();
}
init(){
return exec(`mkdir ${this.root} && cd ${this.root} && git init`);
}
add(file){
return exec(`cd ${this.root} && git add ${file}`);
}
commit(){
return exec(`cd ${this.root} && git commit -m "chore: initial commit"`);
}
}
new Generator()
.execute()
.then(() => console.log('Commited!')
.catch(err => console.error(err));