Javascript 节点上的文件创建问题

Javascript 节点上的文件创建问题,javascript,node.js,Javascript,Node.js,我在使用节点生成文件时遇到问题。这些文件显示的顺序不正确,在创建它们的循环完成后,我的自动git提交发生了错误。有人能帮帮我吗!github回购: 您正在循环中使用异步版本的fs.writeFile,这意味着您不知道将数据写入磁盘的顺序,并且循环不会等待该异步函数的每次调用继续 您必须找到一种方法来知道最后一个文件何时被写入。一种方法是使用同步版本的fs.writeFile函数,其方式如下: execute(){ this.init(); for(let i=0; i<1

我在使用节点生成文件时遇到问题。这些文件显示的顺序不正确,在创建它们的循环完成后,我的自动git提交发生了错误。有人能帮帮我吗!github回购:


您正在循环中使用异步版本的
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));