2016-12-09 92 views
0

我想移動文件使用EasyFTP,但如果我關閉連接,它會在移動任何文件之前關閉,如果我不關閉連接,我會得到一個錯誤。如何讓這段代碼在Node.Js中同步運行?

錯誤:503 RNFR需要第一

因此,這裏是我的代碼

var EasyFtp = require('easy-ftp'); 
var ftp = new EasyFTP(); 
var config = { 
    host: '', 
    port: 21, 
    username: '', 
    password: '' 
}; 

ftp.connect(config); 

var filesFrom=['/file1.txt','/anotherFile.txt','/moreFiles.txt','/a.txt','/x.txt'] 
var filesTo=['/archived/file1.txt','/archived/anotherFile.txt','/archived/moreFiles.txt','/archived/a.txt','/archived/x.txt'] 

for (var i = 0; i < filesFrom.length; i++) { 
    ftp.mv(filesFrom[i], filesTo[i], function(err, newPath){ 
     if (err) { console.log(err) } 
    }); 
}; 

ftp.close(); 
+0

您關閉之前的連接實際上發送請求,只有在所有請求完成時才使用promise和Promise.all來關閉。 – Alon

回答

1

你不能做的事情異步Javascript中同步運行。而且,因爲for循環是同步的,所以在進行下一次迭代之前,不能使for循環等待異步操作完成。所以,相反,你必須爲你的迭代使用不同的技術。有很多不同的選擇。下面是手動迭代,觸發下一次迭代時,前一個是做一個選擇:

function mvFiles(ftpObj, fromArray, toArray, callback) { 
    let index = 0; 
    let results = []; 

    function next() { 
     if (index < fromArray.length) { 
      let i = index++; 
      ftpObj.mv(fromArray[i], toArray[i], function(err, newPath) { 
       if (err) { 
        callback(err); 
       } else { 
        results[i] = newPath; 
        // run next iteration now 
        next(); 
       } 
      }); 
     } else { 
      // all done 
      callback(null, results); 
     } 
    } 

    // start first iteration 
    next(); 
} 

用法:

ftp.connect(config); 

var filesFrom =['/file1.txt','/anotherFile.txt','/moreFiles.txt','/a.txt','/x.txt']; 
var filesTo =['/archived/file1.txt','/archived/anotherFile.txt','/archived/moreFiles.txt','/archived/a.txt','/archived/x.txt']; 

mvFiles(ftp, filesFrom, filesTo, function(err, newPaths) { 
    ftp.close(); 
    if (err) { 
     // process error here 
    } else { 
     // all done here 
    } 
}); 
0

它很容易與藍鳥

var Bluebird = require('Bluebird'); 
var EasyFtp = require('easy-ftp'); 
var ftp = new EasyFTP(); 
var config = { 
    host: '', 
    port: 21, 
    username: '', 
    password: '' 
}; 

// Promisifying adds Async after every method which represents the promise version of that method... you don't have to follow the callback method. 
Bluebird.promisifyAll(ftp); 

ftp.connect(config); 

// push your promises into an array and then Promise.all() it... It will either complete fully or throw an error even if one fails.... All or nothing. 

var promises = []; 

var filesFrom=['/file1.txt','/anotherFile.txt','/moreFiles.txt','/a.txt','/x.txt'] 
var filesTo=['/archived/file1.txt','/archived/anotherFile.txt','/archived/moreFiles.txt','/archived/a.txt','/archived/x.txt'] 

for (var i = 0; i < filesFrom.length; i++) { 
    promises.push(ftp.mvAsync(filesFrom[i], filesTo[i])) 
}; 

// Now promises array contains all the promises and they have started executing. 

Bluebird.all(promises).then(function(results) { 

    // Results is an array of results from all the promises in order. 

    console.log(results); 

    // Close connection. 
    ftp.close(); 
}).catch(function(err) { 
    console.log(err); 
}); 
+0

此代碼同時並行運行所有ftp操作。你知道一個事實,你可以做到這一點?在Bluebird中,你可以使用'Promise.map()'或'Promise.mapSeries()',而不是自己積累promise數組。保存幾行代碼併爲您提供併發控制。 – jfriend00