Как избежать jimp, блокирующего код node.js
Я использую Jimp для манипулирования некоторыми фотографиями.
У меня есть массив с фотографиями. Как это:
var images = ['.../pic-1.jpg', '.../pic-2.jpg', '.../pic-3.jpg', '.../pic-4.jpg'];
И это код для манипулирования ими:
images.forEach(function(image){
jimp.read(image, function(err, img){
img.quality(90, function(){
console.log("done with this image!");
});
});
});
Это работает хорошо, он регистрирует, когда каждое изображение готово. Тем не менее, это блокирует код, и если я попробую это:
var processed = 0;
images.forEach(function(image){
jimp.read(image, function(err, img){
img.quality(90, function(){
processed++;
document.querySelector('p').textContent = 'processed images: ' + processed;
});
});
});
он не обновляет текст, пока все изображения не будут обработаны. Как я могу обойти это так, чтобы я мог обновлять текст каждый раз, когда изображение обрабатывается?
1 ответ
Может показаться, что это происходит потому, что все происходит параллельно, а не последовательно, или, может быть, больше всего времени уходит на img.quality()
и это интенсивная загрузка процессора, которая блокирует основной поток.
Вы можете попробовать изменить это:
images.forEach(function(image){
jimp.read(image, function(err, img){
img.quality(90, function(){
processed++;
document.querySelector('p').textContent = 'processed images: ' + processed;
});
});
});
что-то вроде этого:
let processed = 0;
let f = () => {
jimp.read(images[processed], function(err, img){
img.quality(90, function(){
processed++;
document.querySelector('p').textContent = 'processed images: ' + processed;
if (processed < images.length) setImmediate(f);
});
});
};
Вы также можете изменить setImmediate
в setTimout
с некоторым значением времени ожидания, которое позволит потоку пользовательского интерфейса нарисовать на экране то, что ему нужно нарисовать. Вы могли бы даже использовать window.requestAnimationFrame()
для этого.