在Node.js中异步检索SFTP列表



我正在尝试使用Node从多个服务器检索SFTP列表。我正在使用ssh2-sftp客户端库,并尝试使用futted Promise.all().来处理异步连接

SFTP服务器存储在配置文件(servers.config)中,如下所示:

{
"myhost1": {
"host": "sftp.myhost1.com",
"port": "22 ",
"username":  "userid1",
"password": "password1"
},
"myhost2": {
"host": "sftp.myhost2.com",
"port": "22 ",
"username":  "userid2",
"password": "password2"
},
...
}

我的代码如下。。。

#!/node
let fs = require('fs');
let Client = require('ssh2-sftp-client');
// which servers should we process?
const serverList = fs.readFileSync('./servers.config', {encoding:'utf8', flag:'r'});
const servers = JSON.parse(serverList);
const servers_to_process = Object.keys(servers);
function getDirectoryListing(config) {
let sftp = new Client();
sftp.connect(config)
.then(() => {
return sftp.list('/');
})
.then(data => {
console.log('Data retrieved for: ',config.host);
//console.log(data);  // Line B
sftp.end();
return data;
})
.catch(err => {
console.log('Error for: ',config.host);
return [];
});
}

const processes_to_run = [];
// generate array of promises to run
servers_to_process.forEach( key => {
log('==========================');
log("Provider: "+key+"; "+timestamp);
processes_to_run.push(getDirectoryListing(servers[key]));
});

// wait for all the promises to resolve...
Promise.allSettled(processes_to_run).
then((results) => results.forEach((result) => console.log(result)));

我没有从A行得到任何控制台记录的数据……但如果我取消对B行的注释,我会异步地得到每个列表。

输出看起来像这样:

JSON file read correctly
==========================
Provider: myhost1; 01/06/2021, 14:57:25
==========================
Provider: myhost2; 01/06/2021, 14:57:25
{ status: 'fulfilled', value: undefined }
{ status: 'fulfilled', value: undefined }
Data retrieved for:  sftp.myhost1.com
Data retrieved for:  sftp.myhost2.com

所以,很明显,我在从承诺中返回数据时失误了。。。

这是在处理之前将所有列表放入数组的正确方法吗?考虑到SFTP列表获取的异步性质,是否有更干净的方法?

您需要实际返回函数中的promise-getDirectoryListing()没有返回任何内容。因此,您正在将一个充满undefined的数组传递给Promise.allSettled()

试试这个:

function getDirectoryListing(config) {
let sftp = new Client();
return sftp.connect(config)
.then(() => {
// ...stuff
}

您的getDirectoryListing实际上并没有返回promise。像这样的东西应该对你有用:

#!/node
let fs = require('fs');
let Client = require('ssh2-sftp-client');
// which servers should we process?
const serverList = fs.readFileSync('./servers.config', {encoding:'utf8', flag:'r'});
const servers = JSON.parse(serverList);
const servers_to_process = Object.keys(servers);
//Ensure this is returning a promise by making it async
//and controlling the flow with await rather than callbacks
async function getDirectoryListing(config) {
let sftp = new Client();
await sftp.connect(config)
let list = await sftp.list('/');
console.log('Data retrieved for: ',config.host);
console.log(list);  // Line B
sftp.end();
return list;
}

const processes_to_run = [];
// generate array of promises to run
servers_to_process.forEach( key => {
console.log('==========================');
console.log("Provider: "+key+"; "+Date.now());
processes_to_run.push(getDirectoryListing(servers[key]));
});

// wait for all the promises to resolve...
Promise.allSettled(processes_to_run).
then((results) => results.forEach((result) => console.log(result)));

要使代码正常工作,只需要从函数getDirectoryListing()返回promise,以确保语句执行的正确顺序。

您的解决方案:

function getDirectoryListing(config) {
let sftp = new Client();
return sftp.connect(config) // just add a return here
// ...rest code will be same
}

但你也必须明白为什么会出现这样意想不到的结果。(如果你想了解引擎盖下发生了什么,请阅读本节)

当您调用方法getDirectoryListing()时,您将promise添加到事件循环并返回undefined。由于processes_to_run数组中充满了undefined,因此没有在processes_to_run数组中执行的承诺。这就是为什么执行首先进入console.log(result)

// wait for all the promises to resolve...
Promise.allSettled(processes_to_run).
then((results) => results.forEach((result) => console.log(result)));

一旦事件循环完成了promise,它就会将它们添加到回调队列中,然后对它们进行处理。因此,行A随后被打印。

sftp.connect(config)
.then(() => {
return sftp.list('/');
})
.then(data => {
console.log('Data retrieved for: ',config.host); // Line A
//console.log(data);  // Line B
sftp.end();
return data;
})
.catch(err => {
console.log('Error for: ',config.host);
return [];
});

如果你想了解更多关于事件循环的信息,你可以观看这段精彩的视频。

相关内容

  • 没有找到相关文章

最新更新