Узел JS async/await с несколькими fs.writeFile с использованием through2 (Gulp/Vinyl)

Я использую via2 для создания нескольких файлов из потока Gulp. Я использую NodeJS 10.6.0, поэтому подумал, что в полной мере использую async / await, но пока не до конца разбираюсь в механике. В настоящее время через 2 done() обратный вызов запускается до того, как все файлы были записаны.

Вот что я (упрощенно) - обратите внимание, что я не возвращаю поток в конце, так как в этом нет необходимости.

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

Это не работает как done() возвращается до того, как все файлы были записаны. Я предполагаю, что пропускаю возврат или два, но ничего, что я делаю, кажется, не работает.

Если я пройду done() в doGenerateVariant и позвони после doWriteFile все работает как положено, но я знаю, что это не правильно.

1 ответ

Решение

Вам нужно ждать doGenerateVariant делать свою работу перед звонком done, Помните async Функция всегда возвращает Обещание. Таким образом, вы могли бы сделать это так

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

или используя 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();
    });
};
Другие вопросы по тегам