【问题标题】:Promise called too early承诺过早
【发布时间】:2016-09-13 15:08:21
【问题描述】:

当文件是 JPG 时,它是在返回响应之前创建的(以在浏览器中显示调整大小的图片)。但是当它是 PNG 时,它会在写入 PNG 之前返回,从而导致 Node.Js 服务器崩溃,因为它无法为不存在的东西创建 ReadStream:

调整大小调用

else {
    resizer
        .resizeHandler(filepath, parsedUrl, fullDestinationPath)
        .then(function () {
            return self.send(response, 200, {'Content-Type': mime.lookup(fullDestinationPath)}, fs.createReadStream(fullDestinationPath));
        });
}

调整大小

Resizer.prototype.resizeThenCrop = function(filepath, parsedUrl, fullDestinationPath){
    return Jimp.read(filepath)
        .then(function (picture) {
            var cropWidth = parsedUrl.query.w,
                cropHeight = parsedUrl.query.h;
            calculate(picture, parsedUrl);
                picture.resize(parseInt(parsedUrl.query.w), parseInt(parsedUrl.query.h))
                    .crop(parseInt((parsedUrl.query.w - cropWidth) / 2), parseInt((parsedUrl.query.h - cropHeight) / 2), parseInt(cropWidth), parseInt(cropHeight))
                    .quality(parseInt(parsedUrl.query.quality))
                    .write(fullDestinationPath)
        })
        .catch(function (err) {
            console.error(err);
        });
};

发送

Router.prototype.send = function (response, code, headers, data) {
    response.statusCode = code;

    if (headers) {
        for (var index in headers) {
            if (headers.hasOwnProperty(index)) {
                response.setHeader(index, headers[index]);
            }
        }
    }

    if (data instanceof Stream) {
        data.pipe(response);
    } else {
        response.end(data);
    }
};

但它可能无法处理 PNG 或尝试调整其大小时出错?我已经测试并确认不是这种情况,只需将代码更改为:

else {
        resizer
            .resizeHandler(filepath, parsedUrl, fullDestinationPath)
            .then(function () {
                //return self.send(response, 200, {'Content-Type': mime.lookup(fullDestinationPath)}, fs.createReadStream(fullDestinationPath));
            });
    }

现在它什么也不返回,我的浏览器将永远等待,因为它没有回复。但它确实在文件夹中创建文件,就像它使用 JPG 一样,这意味着它确实有效。在实际创建调整大小的文件之前调用 createReadStream 会导致崩溃,因为该文件不存在。该文件也没有被创建,因为创建它的服务器已经停止。错误:

Error: ENOENT: no such file or directory, open '/var/www/pngbla_w512_h53_q80.png'
    at Error (native)

我可以做些什么来使它在我的 PNG 中正常工作?为什么它不适用于我的 PNG 文件,即使某些 JPG 文件需要 20 秒,因为它已调整为大分辨率。

编辑:我已经尝试了多种尺寸,即使调整大小几乎是即时的 ~5ms,响应仍然会在之前使用 PNG 调用。

【问题讨论】:

    标签: javascript node.js image resize promise


    【解决方案1】:

    显然它已经开始编写 JPG 并且只有在完成后才开始编写 BMP,我使用回调将代码更改为:

    Resizer.prototype.resizeThenCrop = function(filepath, parsedUrl, fullDestinationPath){
        return Jimp.read(filepath)
            .then(function (picture) {
                var cropWidth = parsedUrl.query.w,
                    cropHeight = parsedUrl.query.h;
                calculate(picture, parsedUrl);
    
                return new Promise(function(resolve, reject) {
                    picture.resize(parseInt(parsedUrl.query.w), parseInt(parsedUrl.query.h))
                        .crop(parseInt((parsedUrl.query.w - cropWidth) / 2), parseInt((parsedUrl.query.h - cropHeight) / 2), parseInt(cropWidth), parseInt(cropHeight))
                        .quality(parseInt(parsedUrl.query.quality))
                        .write(fullDestinationPath, function(err) {
                            if(err) {
                                return reject(err);
                            }
    
                            return resolve(fullDestinationPath);
                        });
                });
            })
            .catch(function (err) {
                console.error(err);
            });
    };
    

    问题是 picture.resize 没有返回一个承诺,所以它继续而不等待 .write 完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 2014-03-11
      • 2019-06-15
      • 2016-06-10
      • 2017-12-13
      • 2014-06-16
      • 2016-01-24
      相关资源
      最近更新 更多