【问题标题】:nodejs use gm module to process the images but I need it syncnodejs 使用 gm 模块来处理图像,但我需要它同步
【发布时间】:2016-08-16 10:37:01
【问题描述】:

这里有两种方法。但我需要它来完成同步。但它失败了。 我想使用 Promise.all 来保持同步,但我发现图像处理是异步的,它不能拒绝或循环解决!这真的让我很困惑。 下面是我的代码。我无法捕捉到 res 或错误。它只是在处理完图像后结束......甚至不执行测试方法,但我想知道 Promise.all 是同步方法吗?有什么方法可以捕获 res 或 err 信息?谢谢!

var gm = require('gm')
var fs = require('fs')
var config = require('./imgConfig')
var image = ['1.jpg', '2.jpg', '3.jpg', '4.jpg','5.jpg','6.jpg']
var _image = ['_1.jpg', '_2.jpg', '_3.jpg', '_4.jpg','_5.jpg','6.jpg']


testS()

function testS() {
    uploadFiles(image, _image, 'subModule').then(res => {
        console.log(res)
    }).catch(e => {
        console.log(e)
    })
}

function uploadFiles(inputArray, outputArray, type) {
    return Promise.all([multipleResize(inputArray, outputArray, type), test()])
}

function test() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("object");
            resolve("yeah")
        }, 100)
    })
}


function multipleResize(inputArray, outputArray, type) {
    var height = config[type].height;
    var width = config[type].width;
    return Promise.all(inputArray.map((img, index) => {
        return new Promise((resolve, reject) => {
            gm(config.inputPath + img)
                .resizeExact(width, height)
                .noProfile()
                .write(config.outputPath + outputArray[index], function (err) {
                    if (err) {
                        console.error(err);
                        return reject(err);
                    }
                    try {
                        fs.unlinkSync(config.inputPath + img); // consider using an async method here as well.
                        console.log("next" + config.outputPath + outputArray[index]);
                        console.log('ko');
                        return resolve();
                    } catch (e) {
                        console.error(e);
                        reject(e);
                    }
                });
        });
    }));
}

imgConfig

module.exports = {
        'subModule': {
            width: 300,
            height: 300
        },
        inputPath:'./input/',
        outputPath:'./output/'
    }

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    multipleResolve 中,您正在运行return resolve() 作为#forEach() 调用的一部分。这可能不是您想要的,因为第一次迭代将解决您返回的承诺,即使您的所有 gm .write() 调用尚未完成。

    我会考虑这样做——注意Promise.all()inputArray#map() 的内部使用将每个img/index 对转换为它们自己的Promise。我还交换了一些错误逻辑,以确保尽快检查错误。

    function multipleResize(inputArray, outputArray, type) {
        var height = config[type].height;
        var width = config[type].width;
        var flag = 0;
        return Promise.all(inputArray.map((img, index) => {
            return new Promise((resolve, reject) => {
                gm(config.inputPath + img)
                    .resizeExact(width, height)
                    .noProfile()
                    .write(config.outputPath + outputArray[index], function (err) {
                        if (err) {
                            console.error(err);
                            return reject(err);
                        }
                        try {
                            fs.unlinkSync(config.inputPath + img); // consider using an async method here as well.
                            console.log("next" + config.outputPath + outputArray[index]);
                            flag++;
                            console.log('ko');
                            return resolve();
                        } catch (e) {
                            console.error(e);
                            reject(e);
                        }
                    });
            });
        }));
    }
    

    旁注,您似乎(大部分)正确地使用了 Promise,但是当它们通常不同步时,您错误地调用它们 sync

    【讨论】:

    • 它确实可以捕捉到 res 或 err ,但仍然存在一个问题,当我捕捉到 res 或 err 时,有任何承诺尚未完成..而且我担心他们会导致错误。那么如何解决这个问题呢?我正在更新您提供的代码。有必要运行测试。但我认为加入这种方法会导致这个问题?
    • 原谅我,我很难理解你的英语。 Promise.all() 返回单个 Promise,当您传递给 Promise.all() 的数组中的 每个 承诺完成时,该 Promise 将被解析。通过我的重写,从multipleResize() 返回的Promise 应该解决,直到包裹在gm.write() 调用周围的每个Promise 都已解决。在出现错误的情况下,单个Promise 将在第一个错误时被拒绝,其他所有内容都处于不确定状态(但这是设计使然)。
    • Promise.all() mdn 文档可能对您有所帮助。
    • 对不起我的英语。感谢您的帮助,我终于解决了问题!
    • 没什么好遗憾的。 :) 很高兴你把它整理好了!
    猜你喜欢
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2010-10-15
    • 1970-01-01
    • 2021-04-03
    • 2017-05-15
    相关资源
    最近更新 更多