我可以让 node.js FTP 同步吗?

Can I make node.js FTP synchronous?

我有一个小 FTP 脚本,它基本上将整个目录树(通过 fs.readdir 遍历)传输到 FTP 服务器,一次一个文件(我必须对上传的每个文件进行一些分析,因此是一次一个的行为。

但是,执行单个文件的位(对于使用 c.mkdir 而不是 c.put 的目录还有另一位)看起来像这样:

console.log('Transferring [' + ival + ']');
var c = new Ftp();
c.on('ready', function() {
    c.put(ival, ival, function(err) {
        console.log(err);
    });
    c.end();
});

如您所见,它使用了一种非常简单的登录方法,即失败会简单地发送到控制台。

不幸的是,由于 FTP 是异步完成的,因此错误以与文件名输出完全无关的顺序传送到控制台。

有没有办法强制 FTP 同步完成,以便错误会立即跟在文件名之后?基本上,我希望在继续下一个文件之前完成从初始 console.log 到最终 }); 的整个序列。

即使有也不推荐。您通常不想用这么长的同步操作来阻塞事件循环。

使用递归或 Promises 来确保事情按顺序发生可能更有用。

示例:

let ivals = [/* lots of ivals here */];
function putItems(ivals) {
    let ival = ivals[0];
    console.log('Transferring [' + ival + ']');
    var c = new Ftp();
    c.on('ready', function() {
        c.put(ival, ival, function(err) {
            console.log(err);
            c.end();
            // Don't continue if we're out of items.
            if (ivals.length === 1) { return; } 
            putItems(ivals.slice(1)); // Call again with the rest of the items.
        });
    });
}

putItems(ivals);

使用嵌套函数和单个 FTP 上下文可以更智能地完成此操作。但是你明白了。

你为什么不把错误推到一个数组中,当所有上传完成后,你就会有那个数组 所有这些错误都按顺序排列了吗?

我会做这样的事情:

var errArray = [];
console.log('Transferring [' + ival + ']');
var c = new Ftp();
c.on('ready', function() {
  c.put(ival, ival, function(err) {
    errArray.push( err );
  });
  c.end();
});
c.on('end', function() {
  errArray.forEach( function( err ){
    console.log( err );
  })
});

在不同步的情况下,您可以通过仅记录名称和错误来解决错误记录问题。您可以将其包装在一个闭包中,以便跟踪出现特定错误的 ival

(function(ival) {
    console.log('Transferring [' + ival + ']');
    var c = new Ftp();
    c.on('ready', function() {
        c.put(ival, ival, function(err) {
            console.log('[' + ival + ']', err);
        });
        c.end();
    });
})(ival);