#node.js #fs #node-canvas
#node.js #fs #узел-холст
Вопрос:
Я пытаюсь записать более 100 файлов png через node-canvas в цикле. Генерируется только 40 файлов, а затем процесс завершается.
Я попытался создать поток png с помощью createPNGStream () и передать результаты в поток записи, созданный fs.createWriteStream().
Функция записи:
function writeFile(row, col) {
// canvas code ...
const stream = canvas.createPNGStream();
let path = __dirname '/imgs/heatmapRow' row "Col" col '.png';
const out = fs.createWriteStream(path);
stream.pipe(out);
out.on('finish', () => console.log('The PNG file was created.'))
}
Вызывающая функция:
function generateImages(){
var numRows = 20;
var numCols = 5;
for(let row = 0; row < numRows; row) {
for (let col = 0; col < numCols; col) {
writeFile(row, col);
}
}
}
Цикл запускается и завершается, и в конце я получаю кучу следующих строк одновременно:
Файл PNG был создан. Файл PNG был создан. Файл PNG был создан. Файл PNG был создан.
Я думаю, что в каждом цикле создается поток записи, который является асинхронным. Процесс завершается, потому что у меня может быть открыто только определенное количество потоков.
Как я могу записать все свои файлы и сделать это асинхронно, чтобы ускорить время обработки? (Я предпочитаю не записывать файлы синхронно) Нужно ли добавлять каждый файл для записи в очередь? Как мне определить ограничение на количество открытых мной потоков и как мне управлять ими?
Комментарии:
1. То есть в основном генерируется только 40/100 файлов?. Вы видите какую-либо ошибку?.
2. Это около 40 изображений. Один раз было 37, один раз было 43. У меня не было никаких ошибок.
Ответ №1:
Вы должны использовать Promises для выполнения ваших асинхронных вызовов. Я даю вам решение:
function writeFile(row, col) {
// canvas code ...
const stream = canvas.createPNGStream();
let path = __dirname "/imgs/heatmapRow" row "Col" col ".png";
return new Promise(resolve => {
const out = fs.createWriteStream(path);
stream.pipe(out);
out.on("finish", () => {
console.log("The PNG file was created.");
resolve();
});
});
}
function generateImages() {
var numRows = 20;
var numCols = 5;
var imagesToGenerate = [];
for (let row = 0; row < numRows; row) {
for (let col = 0; col < numCols; col) {
imagesToGenerate.push(writeFile(row, col));
}
}
Promise.all(imagesToGenerate).then(() => {
console.log("All images generated");
});
}
Взгляните на Promise.все документы если вы не совсем понимаете, как это работает