FTP-клиент с асинхронным JavaScript

Я пишу в node.js и использую клиентские модули async.js и ftp.
Я использую async.series, и это функция в async.series:

    var client = new ftp();
client.on('ready', function () {
    for ( var i = 0  ; i < stage._sub_directories.length ; i++ ) {
        var path = get_absolute_path() + DIRECTORY_NAME_LESSONS + stage._name + "/" + DIRECTORY_NAME_STAGE + stage._sub_directories[i];
        var file = 'copy.' + stage._sub_directories[i] + get_xml_file_name();
        client.get(path + "/" + get_xml_file_name(), function (err, stream) {
            console.log('done');
            if (err) throw err;
            stream.once('close', function () {client.end();});
            stream.pipe(fs.createWriteStream(file));
            callback(null, true);
        });
    }
});
client.connect(config);

callback(null, true); для асинхронного модуля. Когда он запускается, его вставить в for петля stage._sub_directories.length раз, а затем вставить в client.get() только один раз (в последний раз).
создано один файл, а не больше.
в чем моя проблема? Я должен использовать другой поток асинхронного управления? или что-то другое?

2 ответа

Решение

То, как написан ваш код, не будет работать, потому что вы вызываете асинхронную функцию, client.getвнутри правильной петли.

Вы должны заменить свой обычный for петля для async.eachSeries метод, так как вы уже используете async.js, Попробуй это:

client.on('ready', function () {
    async.eachSeries(stage._sub_directories, function (subDir, done) {
        var path = get_absolute_path() + DIRECTORY_NAME_LESSONS + stage._name + "/" + DIRECTORY_NAME_STAGE + subDir;
        var file = 'copy.' + subDir + get_xml_file_name();
        client.get(path + "/" + get_xml_file_name(), function (err, stream) {
            if (err) return done(err);
            console.log('done');
            stream.once('close', function () {client.end();});
            stream.pipe(fs.createWriteStream(file));
            done();
        });
    }, function (err) {
        if (err) return callback(err);
        callback(null, true);
    });
});

Честно говоря, разочаровывает, сколько разметки и обнаружения необходимо, чтобы "обойти" эти современные популярные модули FTP... Я автор FTPimp, который я написал специально для решения этой проблемы. Например, вы можете сделать то же самое, используя только модуль ftpimp:

ftp.connect(function () {
    stage._sub_directories.forEach(function (subDir) {
        var path = get_absolute_path() + DIRECTORY_NAME_LESSONS + stage._name + "/" + DIRECTORY_NAME_STAGE + subDir;
        var file = 'copy.' + subDir + get_xml_file_name();
        //save from -> to
        ftp.save([path + "/" + get_xml_file_name(), file], function (err, name) {
            console.log(err, name);
        });
    });
    //@see http://ftpimp.net/FTP.html#event:queueEmpty
    ftp.once('queueEmpty', function () {
        console.log('files saved');
        //do more stuff ...
        ftp.quit();
    });
});
Другие вопросы по тегам