Promise 调用得太早
Promise called too early
当文件是 JPG 时,它是在返回响应之前创建的(以在浏览器中显示调整大小的图片)。但是当它是 PNG 时,它 returns 在它写入 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));
});
}
现在 returns 什么都没有,我的浏览器将永远等待,因为它没有返回响应。但它确实像使用 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 调用响应。
显然它已经开始编写 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 没有 return promise,所以它没有等待 .write 完成就继续了。
当文件是 JPG 时,它是在返回响应之前创建的(以在浏览器中显示调整大小的图片)。但是当它是 PNG 时,它 returns 在它写入 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));
});
}
现在 returns 什么都没有,我的浏览器将永远等待,因为它没有返回响应。但它确实像使用 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 调用响应。
显然它已经开始编写 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 没有 return promise,所以它没有等待 .write 完成就继续了。