节点上的文件创建问题

时间:2018-05-24 13:36:23

标签: javascript node.js

我在使用节点生成文件时遇到问题。这些文件不按顺序显示,并且在创建它们的循环完成之后,完成了我的自动git提交。有谁可以帮助我吗! github repo:https://github.com/wendellmva/cli3

class Generator {
    constructor(){
        this.root = resolve(__dirname, 'generated');
    }   

    clean(done){
        if(fs.existsSync(this.root)){
            trash(this.root).then(done);
        } else {
            done();
        }
    }

    execute(){
        this.init()
        for(let i=0; i<10; ++i) {
            const file = resolve(this.root, `file${i}.txt`);
            fs.writeFile(file, 'Hello world', (err)=> {
                if(err) console.error(err);
                console.info('CREATE ', file);
                if(fs.existsSync(file)) this.add(file);
                if(i==9) this.commit();
            });
        }

    }

    init(){
        shelljs.exec(`mkdir ${this.root} && cd ${this.root} && git init`);
    }
    add(file){
        shelljs.exec(`cd ${this.root} && git add ${file}`);
    }
    commit(){
        shelljs.exec(`cd ${this.root} && git commit -m "chore: initial commit"`);
    }
}

const generator = new Generator();

generator.clean(()=>{
    generator.execute();
});

问题1:在执行完成之前提交启动 导致空提交

问题2:当生成的文件存在时,执行在clean完成之前开始 导致文件已存在错误 ===&GT;解决

问题3:文件是按顺序创建的

Initialized empty Git repository in D:/@cardstrip/cli3/generated/.git/
CREATE  D:\@cardstrip\cli3\generated\file2.txt
CREATE  D:\@cardstrip\cli3\generated\file3.txt
CREATE  D:\@cardstrip\cli3\generated\file0.txt
CREATE  D:\@cardstrip\cli3\generated\file1.txt
CREATE  D:\@cardstrip\cli3\generated\file4.txt
CREATE  D:\@cardstrip\cli3\generated\file5.txt
CREATE  D:\@cardstrip\cli3\generated\file7.txt
CREATE  D:\@cardstrip\cli3\generated\file9.txt
[master (root-commit) 3442284] chore: initial commit
8 files changed, 8 insertions(+)
create mode 100644 file0.txt
create mode 100644 file1.txt
create mode 100644 file2.txt
create mode 100644 file3.txt
create mode 100644 file4.txt
create mode 100644 file5.txt
create mode 100644 file7.txt
create mode 100644 file9.txt
CREATE  D:\@cardstrip\cli3\generated\file6.txt
CREATE  D:\@cardstrip\cli3\generated\file8.txt

2 个答案:

答案 0 :(得分:1)

fs.writeFilechild_process.exec都是异步的,您不会等到操作结束,这就是为什么您的代码没有按预期执行的操作。

我们可以使用writeFileexecutil.promisify转换为基于Promise的API,并使用async/await按正确的顺序执行操作。

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));

您将创建自己的文件&amp;按顺序添加,然后更改将被提交。

答案 1 :(得分:0)

您在循环中使用fs.writeFile的异步版本,这意味着您不知道将数据写入磁盘的顺序以及循环不会等待该异步的每次调用功能继续。

您必须找到一种方法来了解最后一个文件的写入时间。一种方法是使用fs.writeFile函数的同步版本fs.writeFileSync这样:

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();
}