在 NodeJS 中 async/wait 文件保存和锐化图像处理出现问题

Trouble with async/wait file saving and Sharp image processing in NodeJS

我正在尝试为 NodeJS 摄影网站制作后端,但我在使用 Sharp 处理图像然后将它们上传到 AWS S3 时遇到了障碍。 NodeJS 的异步方法打乱了处理过程,因为它会在文件开始写入后立即上传文件,从而引发错误。我已经精简了下面的图像处理代码,以便更容易地进行故障排除。

预期结果

  1. 文件从临时表单上传文件夹中保存(在此 例如,我只是将随机图像粘贴在“uploads/”目录中) 到一个处理文件夹(在这个例子中,一个名为 “保存/”)
  2. 所有文件都转换为WEBP格式并另存为新文件 文件。
  3. 完成所有 WEBP 转换后,一切都应该是 上传到S3,然后删除本地文件。

我已经设法让初始保存和 WEBP 转换步骤同步工作,但我不知道如何让 upload/delete 函数等到 WEBP 文件保存之后。它一直等到 WEBP 转换开始后,然后每个文件的承诺在 upload/delete 函数触发后解析。

const fs = require('fs')
const path = require('path')
const formidable = require('formidable')
const moment = require('moment')
const sharp = require('sharp')
const dotenv = require("dotenv")
const AWS = require('aws-sdk');

const saveParams = {
    uploadDir: 'upload/',
    saveDir: 'save/'
};

const timeNow = moment().format();

for (const [key, value] of Object.entries(saveParams)) {
    console.log('Checking for ' + value + ' directory')
    if (!fs.existsSync(value)) {
        new Promise((resolve, reject) => {
            console.log(value + ' does not exist—creating it now.')
            fs.mkdirSync(value);
            console.log('Created directory: ' + value)
            resolve();
        });
    }
}

function check(file) {
    console.log('Checking ' + file + ' status.')
    if (fs.existsSync(file)) {
        console.log('File exists at ' + timeNow)
        return (true);
    } else {
        return (false)
    }
}

function checkSave(saveParams, file) {
    if (fs.existsSync(saveParams.saveDir + file)) {
        return ('File already exists')
    } else {
        const startTime = moment().format()
        const data = fs.readFileSync(saveParams.uploadDir + file)
        fs.writeFileSync(saveParams.saveDir + file, data)
        const stopTime = moment().format()
        if (check(saveParams.saveDir + file)) {
            return (file + ' saved at ' + moment().format());
        } else {
            throw new Error(file + "didn't save.")
        }
    }
}

async function sharpAwaitWEBP(saveParams, file, webpFile) {
    const data = await sharp(saveParams.saveDir + file)
        .webp({ lossless: true })
        .toBuffer((err, data, info) => {
            return new Promise((resolve, reject) => {
                fs.writeFileSync(webpFile, data)
                if (err => {
                    console.log(err)
                })
                    console.log('Resolving ', webpFile)
                resolve(webpFile)
            })
        });
};


function webpSave(saveParams, file) {
    var extension = file.substr(file.lastIndexOf('.'));
    var baseName = path.basename(file, extension);
    var webpFile = saveParams.saveDir + baseName + '.webp'
    if (fs.existsSync(webpFile)) {
        return ('File already exists')
    } else {
        new Promise((resolve, reject) => {
            sharpAwaitWEBP(saveParams, file, webpFile);
        })
    }
};

function webpSaveWrapper(files2) {
    return new Promise((resolve, reject) => {
        files2.forEach(file => {
            var extension = file.substr(file.lastIndexOf('.'));
            if (extension !== '.webp' && (extension === '.jpg' || extension === '.png')) {
                console.log('Starting WEBP function.')
                webpSave(saveParams, file)
            }
            resolve();
        });
    })

}

function uploadtoS3(saveParams) {
    console.log('Uploading all files to S3') // Will be a function here to upload all saved and converted files to an S3 bucket
    console.log('Deleting everything. Buh bye now.') // This will delete all local files after they've been uploaded to S3
}


async function processImages(saveParams) {
    console.log('Process started at ' + timeNow);
    const files1 = fs.readdirSync(saveParams.uploadDir);
    files1.forEach(file => {
        console.log('Starting checkSave function.')
        console.log(checkSave(saveParams, file))
    });

    const files2 = fs.readdirSync(saveParams.uploadDir);
    await webpSaveWrapper(files2)
    uploadtoS3(saveParams)
}

processImages(saveParams);

记录以上代码的输出

[nodemon] starting `node app.js`
Checking for upload/ directory
Checking for save/ directory
Process started at 2021-03-28T02:42:57-05:00
Starting checkSave function.
File already exists
Starting checkSave function.
Checking save/randomimage-01.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-01.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-02.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-02.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-03.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-03.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-04.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-04.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-05.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-05.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-06.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-06.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-07.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-07.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-08.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-08.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-09.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-09.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-10.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-10.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-11.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-11.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-12.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-12.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-13.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-13.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-14.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-14.jpg saved at 2021-03-28T02:42:57-05:00
Starting checkSave function.
Checking save/randomimage-15.jpg status.
File exists at 2021-03-28T02:42:57-05:00
randomimage-15.jpg saved at 2021-03-28T02:42:57-05:00
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Starting WEBP function.
Uploading all files to S3 //This line and the next one should come after the "Resolve..." lines
Deleting everything. Buh bye now.
Resolving  save/randomimage-02.webp
Resolving  save/randomimage-01.webp
Resolving  save/randomimage-03.webp
Resolving  save/randomimage-04.webp
Resolving  save/randomimage-05.webp
Resolving  save/randomimage-08.webp
Resolving  save/randomimage-06.webp
Resolving  save/randomimage-11.webp
Resolving  save/randomimage-09.webp
Resolving  save/randomimage-07.webp
Resolving  save/randomimage-12.webp
Resolving  save/randomimage-13.webp
Resolving  save/randomimage-14.webp
Resolving  save/randomimage-15.webp
Resolving  save/randomimage-10.webp

非常感谢任何帮助。这显然超出了我对 NodeJS 的适应范围,并且当我可以将我的站点保留在 Wordpress 而不是自定义 Node 站点时,这完全是多余的。

我用 for (const file of files) {//image processing functions} 而不是 forEach 循环解决了这个问题