node.js асинхронно скачивает несколько файлов с помощью fs writestream - PullRequest
0 голосов
/ 27 марта 2020

после выполнения первого вопроса без ответа Node.js Javascript не загружать изображения из массива (вы можете увидеть мой первый код внутри комментария) Я работал над своим кодом и искал кого-то другого у меня была та же самая проблема (найдена здесь без ответа Node.js Асинхронная загрузка нескольких файлов ), поэтому я наблюдал, как он ввел очередь загрузки, чтобы попытаться выполнить асинхронные обратные вызовы, но пытаясь разрешить fini sh сначала, чтобы загрузить следующий, поэтому я попытался выяснить, в чем может быть проблема, может, может быть, программа не закончила первый Writestream до того, как запустит другой, поэтому я попробовал что-то вроде file.on("close", function() {, если не с "close" хотя бы с "end", но это только что заблокировали, чтобы попытаться загрузить первый файл с ошибкой. так что мой вопрос в том, что мне не хватает в обратных вызовах? Зачем скачивать только последний файл?

        const FILEPATH = "mypath/myfolder/" 
        const HREFSFILENAME = "urls.txt"
        var NodeHelper = require("node_helper")
        var fs = require("fs");
        var http = require('http');
        var urls;/*[] = new Array();*/
        var url = "";
        filename = "";
        var regex    = /(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/;

module.exports = NodeHelper.create({        

      start: function() {
        fs.readFile(FILEPATH + HREFSFILENAME, "utf8", function (err,data) {
          if (err) return console.log(err);
          urls = data.split("\n")
          for (i=0; i < urls.length; i++) {
            console.log("ROW" + i + ": " + urls[i])
            url = urls[i]
            if (!url.match(regex)) continue;
            filename = FILEPATH + url.substring(url.lastIndexOf('/') + 1)
            downloadQueue.addItem(url, filename);
          }

        /*
          for (let i=0; i < urls.length; i++) {
              var request = http.get(urls[i], function(response) {
                console.log("GET" + i)
                var filename = urls[i]
                filename = filename.substr(filename.lastIndexOf("/") + 1)
                console.log("FILENAME: " + filename)
                filename = FILEPATH + filename
                var file = fs.createWriteStream(filename);
                response.on("end", function() {
                  file.end();
                });
                response.pipe(file);
              });
          }*/
        });
      },
    })
            var downloadQueue = {
                queue: [],
                addItem: function(p_sSrc, p_sDest) {
                    this.queue.push({
                        src: p_sSrc,
                        dest: p_sDest
                    });
                    if (this.queue.length === 1) {
                        this.getNext();
                    }
                },
                getNext: function() {
                    var l_oItem = this.queue[0];
                    http.get(l_oItem.src, function(response) {
                        console.log("Downloading: " + l_oItem.dest);
                        var file = fs.createWriteStream(l_oItem.dest);
                        response.on("end", function() {
                            file.end()
                            console.log("Download complete.");
                            //file.on("close", function() {
                              downloadQueue.removeItem();
                            //});
                        }).on("error", function(error) {
                            console.log("Error: " + error.message);
                            fs.unlink(l_oItem.dest);
                        });
                        response.pipe(file);
                    });
                },
                removeItem: function() {
                    this.queue.splice(0, 1);
                    if (this.queue.length != 0) {
                        this.getNext();
                    } else {
                        console.log("All items downloaded");
                    }
                }
            };

Мой журнал на самом деле таков, и, как вы можете видеть, он загружает только последнее изображение

    [16:45:51.266] [LOG]    ROW0: http://link1/image1.jpg
    [16:45:51.271] [LOG]    ROW1: http://link2/image2.png
    [16:45:51.271] [LOG]    ROW2: http://link3/image3.png
    [16:45:52.336] [LOG]    Downloading: myPath/myfolder/image1.jpg
[18:10:58.456] [LOG]    Download complete.
[18:10:58.459] [LOG]    Whoops! There was an uncaught exception...
[18:10:58.459] [ERROR]  { [Error: ENOENT: no such file or directory, open 'C:\Users\kenzo\myPath\myfolder\image1.jpg
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path:
   'C:\\Users\\kenzo\\mypath\\myfolder\\image1.jpg\r' }
[18:10:58.736] [LOG]    Downloading: myPath/myfolder/image2.png
[18:10:58.736] [LOG]    Download complete.
[18:10:58.737] [LOG]    Whoops! There was an uncaught exception...
']8:10:58.737] [ERROR]  { [Error: ENOENT: no such file or directory, open 'C:\Users\kenzo\myPath\myfolder\image2.png
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path:
   'C:\\Users\\kenzo\\myPath\\myfolder\\image2.png\r' }
[18:10:58.994] [LOG]    Downloading: mmyPath/myfolder/image3.png
[18:10:59.026] [LOG]    Download complete.
[18:10:59.026] [LOG]    All items downloaded

1 Ответ

0 голосов
/ 27 марта 2020

Выглядит как проблема с функцией getNext, вы всегда принимаете queue[0]

getNext: function() {
           var l_oItem = this.queue[0];

Вы можете использовать обещанную базовую цепочку, чтобы решить асинхронную проблему c. Здесь readFile представляет асинхронную c операцию чтения. Иначе используйте asyn c -wait, чтобы сделать этот очиститель.

// Solution 3.1: Using promise
const promiseReadFile = (name) => {
    return new Promise((resolve, _) => {
        readFile('promise', name, resolve)
    })
}
const p1 = promiseReadFile(files[0])
const p2 = promiseReadFile(files[1])
const p3 = promiseReadFile(files[2])
console.time("PROMISE: TOTAL_TIME")
p1
    .then(console.log)
    .then(() => p2)
    .then(console.log)
    .then(() => p3)
    .then(console.log)
    .then(console.timeEnd.bind(null, "PROMISE: TOTAL_TIME"))
// Solution 3.2: Using promise accumulator
console.time("PROMISE-V2: TOTAL_TIME")
files
    .map(promiseReadFile)
    .reduce((chain, pr) => {
        return chain.then(() => pr)
            .then(console.log)
    }, Promise.resolve())
    .then(console.timeEnd.bind(null, "PROMISE-V2: TOTAL_TIME"))

Подробнее: https://gist.github.com/deepakshrma/1a899bf49ccb77d3b5be771907b32e4c

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...