简体   繁体   English

使用through2(Gulp / Vinyl)与多个fs.writeFile进行节点JS异步/等待

[英]Node JS async/await with multiple fs.writeFile using through2 (Gulp/Vinyl)

I'm using through2 to generate multiple files from a Gulp stream. 我正在使用through2从Gulp流中生成多个文件。 I'm using NodeJS 10.6.0 so thought I'd make full use of async/await, but am not fully understanding the mechanics yet. 我正在使用NodeJS 10.6.0,因此以为我会充分利用async / await,但尚未完全了解其机制。 Currently the through2 done() callback is being fired before all files have been written. 当前,在写入所有文件之前,将触发through2 done()回调。

Here's what I have (simplified) - note that I'm not returning the stream at the end as there is no need to. 这是我(简化)的内容-请注意,由于不需要,我不会在最后返回流。

async function createDirectory(pathDir) {
    return new Promise((resolve, reject) => {
        mkdirp(pathDir, (err) => {
            if (err) reject(err);
            else resolve();
        });
    });
}

async function writeFile(outputFilePath, outputFileContent) {
    return new Promise((resolve, reject) => {
        fs.writeFile(outputFilePath, outputFileContent, (err) => {
            if (err) reject(err);
            else resolve();
        });
    });
}

async function doWriteFile(outputFolderPath, outputFilePath, outputContent) {
    await createDirectory(outputFolderPath);
    await writeFile(outputFilePath, outputContent, outputContent);
}

async function doGenerateVariant(data, variantArr) {
    for (const variant of variantArr) {

        /* Do a load of stuff */

        const variantOutputFolderPath = blah;
        const variantOutputFilePath = blah;
        const variantOutputContent = blah;

        await doWriteFile(variantOutputFolderPath, variantOutputFilePath, variantOutputContent);
    }
}

const generateVariant = () => {
    return through.obj((file, enc, done) => {
        const data = JSON.parse(file.contents.toString());

        */ Do a load of stuff */

        const { variant } = data;
        const variantArr = Object.values(variant);
        doGenerateVariant(data, variantArr);
        return done();
    });
};

This doesn't work as done() gets returned before all files have been written. 这不起作用,因为在写入所有文件之前返回done() I'm guessing I'm missing a return or two but nothing I do seems to be working. 我猜我错过了一两个回报,但我似乎没有做任何事情。

If I pass done() into doGenerateVariant and call it after doWriteFile everything works as expected but I know this isn't correct. 如果我将done()传递给doGenerateVariant并在doWriteFile之后调用它,一切都会按预期进行,但是我知道这是不正确的。

You need to wait for doGenerateVariant to do its job before calling done . 您需要等待doGenerateVariant完成其工作,然后再调用done Remember async function always returns a Promise. 记住async函数总是返回一个Promise。 So you could do it this way 所以你可以这样

const generateVariant = () => {
    return through.obj((file, enc, done) => {
        const data = JSON.parse(file.contents.toString());

        */ Do a load of stuff */

        const { variant } = data;
        const variantArr = Object.values(variant);
        doGenerateVariant(data, variantArr).then(() => done());
    });
};

or using async/await 或使用async/await

const generateVariant = () => {
    return through.obj(async (file, enc, done) => {
        const data = JSON.parse(file.contents.toString());

        */ Do a load of stuff */

        const { variant } = data;
        const variantArr = Object.values(variant);
        await doGenerateVariant(data, variantArr);
        done();
    });
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM