如何检测Node.js

时间:2017-02-11 20:34:14

标签: 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 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'数组。据我所知,这个搜索工作正在成功地将所有目录名称推送到数组。

但是,我想不出一种方法可以检测到所有目录的递归搜索何时完成,所以我可以对'serverPaths'数组做些什么。

我试图利用Promise.all(),但在知道多少函数调用未知时,不知道如何使用它。

2 个答案:

答案 0 :(得分:0)

向我发出的主要事情之一是你最初的if语句。 (如果paths.length> 0){run recursion}这似乎对第一次调用非常有效,因为你知道回来的数据将填充一个充满目录的数组。

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

尝试添加逻辑来处理长度为零的数组的情况if(paths.length === 0)返回; |这将是对堆栈较高部分的递归调用的一个难以突破。

答案 1 :(得分:0)

您只缺少几个return,添加Promise.allArray#map并且您已完成

注意:不要在Promise.all上使用serverPaths,而是使用.then中返回Promise这一事实将导致.then获取的Promise在返回的Promise上(嗯,这个解释不是很好,是的,但它确实是Promises 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}`);
            })
    }));
}