#javascript #node.js
Вопрос:
Я пытаюсь загрузить более 10 000 изображений с CDN-сервера. Однако, когда я использовал следующий код, скрипт просто создает кучу пустых файлов, и загружается только последний. Кроме того, я получил массу ошибок, в том числе MaxListenersExceededWarning и EMFILE, слишком много открытых файлов. Как решить эту проблему? Спасибо.
const http = require('https'); // or 'https' for https:// URLs
const fs = require('fs');
for (let i = 1; i <= 500; i ) {
var random = Math.floor(Math.random() * 1497791);
var url = "https://cdnpath.com" random ".png";
//var dest = "D:/SavePath/" random ".png";
var file = fs.createWriteStream("D:/SavePath/#" i ".png");
var request = http.get(url, function(response) {
response.pipe(file).end();
});
setTimeout(sleep, 3000);
}
Ответ №1:
Я включаю только соответствующий код. Проблема в том, что асинхронные функции не будут блокировать поток выполнения, ожидающий завершения, прежде чем продолжить выполнение. Это означает, что вы увеличите значение в цикле и получите значение 500 за меньшее время, необходимое для завершения асинхронных операций, поэтому в конце вы запишете только последнее содержимое файла
Это может решить вашу проблему
const saveFile = (counter, rndNumber) => {
var url = "https://cdnpath.com" random ".png";
var file = fs.createWriteStream("D:/SavePath/#" counter ".png");
http.get(url, function(response) {
response.pipe(file).end();
});
}
for (let i = 1; i <= 500; i ) {
var random = Math.floor(Math.random() * 1497791);
saveFile(i, random);
}
Это может вызвать проблемы с перегрузкой на сервере, поэтому вы можете использовать лучший подход, используя async/await или обещания в своем коде, чтобы ограничить количество одновременных вызовов на сервер.
Комментарии:
1. Попробовал это решение, но получил ошибку [ERR_STREAM_WRITE_AFTER_END]: запись после завершения в потоке записи. Доступно для записи. запись (внутренние/потоки/доступные для записи.js:292:11) в IncomingMessage.ondata (внутренние/потоки/читаемые.js:726:22) в IncomingMessage.emit (события.js:400:28) в IncomingMessage. Читается.считывается (внутренний/потоки/читаемый.js:500:10) в потоке (внутренний/потоки/читаемый.js:982:34)
2. Я отредактировал пример, похоже, что fs.createWriteStream также является асинхронной функцией, и вам нужно дождаться завершения создания, прежде чем вызывать URL-адрес и писать ответ. Было бы проще помочь, если бы вы предоставили пример работы jsfiddler с вашим кодом
3. Ошибка типа: fs.createWriteStream(…).тогда это не функция в файле сохранения (D:Minecraftapp.js:7:63)
4. У меня была ошибка с переменной i, можете ли вы попробовать это сейчас? replit.com/languages/nodejs Я проверил это здесь и, кажется, работает