2017-03-24 72 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