我知道这是我已经深入研究的一些异步难题,但是我试图在任何npm的各种FTP软件包的.list
方法的回调中下载多个文件。
这样的事情(注意:这里的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' }
答案 0 :(得分: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.`)
})
}
})
&#13;
但是我建议使用某种流控制库,例如async
或使用基于promise的解决方案,因为它可能更容易管理。
使用我提到的async
模块,在类似的解决方案上也存在类似的问题:Downloading multiple file from ftp site using node js