2017-03-24 70 views
1

我使用Jimp来操纵一些照片。如何避免jimp阻止代码node.js

我有一张照片阵列。就像这样:

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

它不更新文本,直到处理完所有图像。我怎样才能解决这个问题,这样我就可以在每次处理图像时更新文本?

+0

超时工作。这将确保它发生在下一个事件中。 – bhspencer

+0

我不明白对不起,怎么这样? – nick

+0

我在这段代码中看不到任何阻塞。内部forEach所有调用似乎是异步的。 – Ananth

回答

0

看起来可能是这样,因为所有事情都是并行发生的,而不是按顺序发生,或者确实大部分时间都花在img.quality()之上,而且这是一个CPU密集型任务,会阻塞主线程。

你可以尝试改变这一点:

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

您还可以更改setImmediatesetTimout一些超时值,将让UI线程上的画画出它需要画的东西。你甚至可以使用window.requestAnimationFrame()

+0

关于setImmediate的声明不完全正确。 setImmediate将被添加到事件列表的末尾。绘制事件将在它之前发生您不需要使用setTimeout来让UI绘制。 – bhspencer