2016-06-22 53 views
2

我知道這是我自己介入的一些異步難題,但我試圖從npm的各種FTP軟件包的.list方法的回調中下載多個文件。節點FTP:循環內的多個異步調用

因此,像這樣(注:這裏JSFTP是隻是一個包裝圍繞node-ftp,我得到了同樣的問題與一個):

ftp = new JSFTP(conf.FTPConfig) 
    ftp.ls(conf.remoteFolder, (err, fileList) => { 
    if (err) return console.error(err) 

    for (let i=0; i<fileList.length; i++){ 
     file = fileList[i] 
     ftp.get(file.name, `./Downloaded/${file.name}`, err => { 
     if (err) return console.error(err) 
     console.log(`${file.name} copied.`) 
     }) 
    } 
    }) 

如果我不使用循環和只下載一個文件,一切正常。 但隨着一個循環,我不斷收到以下錯誤,我沒有得到任何文件(除了一個或兩個空文件佔位符):

(總之):Error: 503 Bad sequence of commands,並在下面進一步:'Probably trying a PASV operation while one is in progress

它看起來好像在循環內啓動了所有的.get調用(顯然沒有等待它們中的任何一個完成,這很好),但是卻無法以這種方式實際執行所有.get調用? 它們不應該只是異步並行運行嗎?

{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: 503 Bad sequence of commands. 
    at Ftp.parse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:257:11) 
    at Ftp.parseResponse (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:174:8) 
    at Stream.<anonymous> (C:\Git\SenecaFTP\FTPMonitor\node_modules\jsftp\lib\jsftp.js:146:24) 
    at emitOne (events.js:96:13) 
    at Stream.emit (events.js:188:7) 
    at ResponseParser.reemit (C:\Git\SenecaFTP\FTPMonitor\node_modules\duplexer\index.js:70:25) 
    at emitOne (events.js:96:13) 
    at ResponseParser.emit (events.js:188:7) 
    at readableAddChunk (_stream_readable.js:172:18) 
    at ResponseParser.Readable.push (_stream_readable.js:130:10) code: 503 } 
{ Error: connect ECONNREFUSED 192.168.100.161:61229 
    at Object.exports._errnoException (util.js:1007:11) 
    at exports._exceptionWithHostPort (util.js:1030:20) 
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14) 
    code: 'ECONNREFUSED', 
    errno: 'ECONNREFUSED', 
    syscall: 'connect', 
    address: '192.168.100.161', 
    port: 61229, 
    msg: 'Probably trying a PASV operation while one is in progress' } 

回答

3

從源頭上尋找jsftp後,似乎是創建一個單獨的連接,並只使用一個插座:https://github.com/sergi/jsftp/blob/master/lib/jsftp.js#L120

這意味着它不會爲每個命令一個新的連接,但使用通過單個連接發送命令。基本上你可以繞過這個過程,就是爲每個你想上傳的文件創建一個新的SFTP實例。

基本上返工的代碼如下:

ftp = new JSFTP(conf.FTPConfig) 
 
    ftp.ls(conf.remoteFolder, (err, fileList) => { 
 
    if (err) return console.error(err) 
 

 
    for (let i=0; i<fileList.length; i++){ 
 
     file = fileList[i] 
 
     new JSFTP(conf.FTPConfig).get(file.name, `./Downloaded/${file.name}`, err => { 
 
     if (err) return console.error(err) 
 
     console.log(`${file.name} copied.`) 
 
     }) 
 
    } 
 
    })

不過,我會建議使用某種流量控制庫如async或利用基於承諾的解決方案,因爲它可能是一個更容易管理。

也有類似的問題上所以用類似的解決方案使用async模塊我提到:Downloading multiple file from ftp site using node js

+0

是啊這幫助很大,非常感謝!我最終選擇了上面提到的簡單路線。我應該在未來嘗試一下Async庫。但現在,這只是一個概念驗證所需要的。再次感謝! – batjko