Javascript 如何在Node.js中检测多个数组的多个异步调用何时完成

Javascript 如何在Node.js中检测多个数组的多个异步调用何时完成,javascript,node.js,promise,sftp,Javascript,Node.js,Promise,Sftp,我使用[ssh2 sftp client][1]包递归读取给定远程路径中的所有目录 这是代码 const argv = require('yargs').argv; const client = require('ssh-sftp-client'); const server = new Client(); const auth = { host: '192.168.1.11', username: argv.u, password: argv.p }; const s

我使用[ssh2 sftp client][1]包递归读取给定远程路径中的所有目录

这是代码

const argv = require('yargs').argv;
const client = require('ssh-sftp-client');
const server = new Client();
const auth = {
    host: '192.168.1.11',
    username: argv.u,
    password: argv.p
};

const serverRoot = '/sites/';
const siteName = 'webmaster.com';

// list of directories on the server will be pushed to this array
const serverPaths = [];

server.connect(auth).then(() => {
    console.log(`connected to ${auth.host} as ${auth.username}`);
}).catch((err) => {
    if (err) throw err;
});

server.list('/sites/').then((dirs) => {
    redursiveDirectorySearch(dirs, `${serverRoot}${siteName}/`);
})
.catch((err) => {
    if (err) throw err;
});

function recursiveDirectorySearch(dirs, prevPath) {
    let paths = dirs.filter((dir) => {
    // returns directories only
        return dir.type === 'd';
    });

    if (paths.length > 0) {
        paths.forEach((path) => {
            server
                .list(`${prevPath}${path.name}`)
                .then((dirs) => {
                    console.log(`${prevPath}${path.name}`);
                    recursiveDirectorySearch(dirs, `${prevPath}${path.name}`);
                    serverPaths.push(`${prevPath}${path.name}`);
                })
        }
    }
}
首先,将与服务器建立连接,然后列出“/sites/”目录下的内容,然后将这些内容传递给“recursiveDirectorySearch”函数。此函数将接收在服务器上的“/sites/”目录下找到的任何内容的数组作为第一个参数,该数组将被过滤掉,因此它只有目录。如果找到一个或多个目录,将为数组中的每个目录调用服务器,以便检索“/sites/”+“数组中目录的名称”下的所有内容。在找不到其他目录之前,将使用调用服务器返回的任何内容再次调用相同的函数

每当找到目录时,其字符串名称将被推送到“serverPaths”数组中。据我所知,此搜索正在工作,并成功地将所有目录名推送到数组中

但是,我想不出一种方法来检测对所有目录的递归搜索何时完成,这样我就可以对“ServerPath”数组做些什么了


我试图利用Promise.all()的优势,但不知道在进行了多少次函数调用时如何使用它。

我突然想到的一个主要问题是您的初始if语句。(如果paths.length>0){run recursion}这对于第一次调用似乎非常有效,因为您知道返回的数据将填充满目录的数组

但是,您的函数似乎没有为长度为0的数组构建逻辑。在这种情况下,您可以获取所有正在查找的目录名。以您想要的方式呈现。这也意味着您对树的更高部分的调用永远无法解决


尝试添加逻辑来处理长度为零的数组的案例| if(path.length==0)return;|这将很难打破堆栈更高部分的递归调用

您只是缺少几个
返回
s,添加一个
承诺。全部
,和一个
数组#映射
,就完成了

注意:不要使用
承诺。所有
服务器路径上的
,而是使用在
中返回承诺的事实。然后
将导致
返回的承诺。然后
接受返回的承诺(嗯,这不是很好地解释,是吗,但它确实是承诺101之类的东西

server.list('/sites/').then((dirs) => {
    // added a return here
    return recursiveDirectorySearch(dirs, `${serverRoot}${siteName}/`);
})
.then(() => {
    // everything is done at this point,
    // serverPaths should be complete
})
.catch((err) => {
    if (err) throw err;
});

function recursiveDirectorySearch(dirs, prevPath) {
    let paths = dirs.filter((dir) => {
    // returns directories only
        return dir.type === 'd';
    });
    // added a return, Promise.all and changed forEach to map
    return Promise.all(paths.map((path) => {
        //added a return here
        return server
            .list(`${prevPath}${path.name}`)
            .then((dirs) => {
                console.log(`${prevPath}${path.name}`);
                // swapped the next two lines
                serverPaths.push(`${prevPath}${path.name}`);
                // added a return here, push the path before
                return recursiveDirectorySearch(dirs, `${prevPath}${path.name}`);
            })
    }));
}

我试图以这样一种方式更改代码,
传递到
。然后,
在那里完成的是一个
服务器路径数组
,这样你甚至不需要
服务器路径
数组-但我不知怎的迷路了:p这应该是可能的,但我今天还不够!!