1

I'm using Jimp to manipulate some photos.

I have an array with photos. Like this:

var images = ['.../pic-1.jpg', '.../pic-2.jpg', '.../pic-3.jpg', '.../pic-4.jpg'];

And this is the code for manipulating them:

images.forEach(function(image){
  jimp.read(image, function(err, img){
    img.quality(90, function(){
      console.log("done with this image!");
    });
  });
});

This works nice it logs when each image is done. However, it's blocking the code and if I try this:

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;
    });
  });
});

it doesn't update the text until all the images are processed. How can I work this around so I can update the text each time an image gets processed?

TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94
nick
  • 2,819
  • 5
  • 33
  • 69

1 Answers1

0

It may seem like this because everything happens in parallel instead of in sequence, or maybe indeed the most time is spent in img.quality() and it's a CPU-intensive task that blocks the main thread.

You can try changing this:

images.forEach(function(image){
  jimp.read(image, function(err, img){
    img.quality(90, function(){
      processed++;
      document.querySelector('p').textContent = 'processed images: ' + processed;
    });
  });
});

to something like this:

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);
    });
  });
};

You can also change setImmediate to setTimout with some timeout value that would let the UI thread to draw on the screen what it needs to draw. You could even use the window.requestAnimationFrame() for that.

rsp
  • 107,747
  • 29
  • 201
  • 177
  • Your statement about setImmediate is not quite correct. setImmediate will be added to the end of the event list. Draw events will happen before it You do not need to use setTimeout to let the UI draw. – bhspencer Mar 24 '17 at 22:29