简体   繁体   English

节点FTP:循环内有多个异步调用

[英]Node FTP: Multiple asynchronous calls inside loop

I know this is some async conundrum I have gotten myself into, but I am trying to download multiple files, inside the callback from the .list method of any of npm's various FTP packages. 我知道这是我遇到的一个异步难题,但是我正在尝试从npm的各种FTP软件包中的.list方法的回调中下载多个文件。

So something like this (note: JSFTP here is just a wrapper around node-ftp , I get the same issue with that one): 所以是这样的(注意:这里的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.`)
      })
    }
  })

If I don't use a loop and only download one file, everything works fine. 如果我不使用循环,而仅下载一个文件,则一切正常。 But with a loop, I keep getting the following errors and I don't get any of the files (except one or two empty file placeholders): 但是通过循环,我不断收到以下错误,但没有任何文件(一个或两个空文件占位符除外):

(In short): Error: 503 Bad sequence of commands , and further below: 'Probably trying a PASV operation while one is in progress (简而言之): Error: 503 Bad sequence of commands ,以及更进一步的内容: 'Probably trying a PASV operation while one is in progress

It looks like it kicks off all my .get calls inside the loop (obviously without waiting for any of them to finish, which is fine), but then fails to actually execute all the .get calls this way? 看起来它在循环内启动了我的所有.get调用(显然不等待它们中的任何一个完成,这很好),但是随后是否无法以这种方式实际执行所有.get调用? Should they not just run in parallel, asynchronously? 他们不应该只是异步并行运行吗?

{ 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' }

After looking at the source for jsftp it appears that is creates a single connection and uses just one socket: https://github.com/sergi/jsftp/blob/master/lib/jsftp.js#L120 在查看jsftp的源代码之后,似乎创建了一个连接并仅使用一个套接字: https//github.com/sergi/jsftp/blob/master/lib/jsftp.js#L120

This means that it does not create a new connection for each command, but uses a single connection to send the commands through. 这意味着它不会为每个命令创建新的连接,而是使用单个连接来发送命令。 Basically how you can circumvent that is by creating a new SFTP instance for each file that you want to upload. 基本上,您可以通过为要上传的每个文件创建一个新的SFTP实例来规避该问题。

Basically reworking the code to this: 基本上将代码修改为:

 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.`) }) } }) 

However I would recommend using some sort of a flow control library such as async or utilizing a promise based solution as it might be a little more manageable. 但是,我建议您使用某种流控制库(例如async或使用基于Promise的解决方案,因为它可能更易于管理。

There is also a similar question on SO with a similar solution using the async module I mentioned: Downloading multiple file from ftp site using node js 使用我提到的async模块,使用类似的解决方案在SO上也存在类似的问题: 使用节点js从ftp站点下载多个文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM