nodejs使用gm模块处理图像,但我需要它同步

时间:2016-04-22 17:21:17

标签: javascript node.js

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

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/'
    }

1 个答案:

答案 0 :(得分:1)

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

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

Promise

旁注,您似乎正在使用promises(大多数情况下),但是当它们通常不同步时,您错误地调用了它们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); } }); }); })); }