简体   繁体   English

完成后无法退出我的进程。 节点

[英]unable to exit my process after completion. NodeJS

I'm working on a Node JS program to connect to a remote SFTP server to copy log files.我正在开发一个 Node JS 程序来连接到远程 SFTP 服务器以复制日志文件。 I'm using this NPM package.我正在使用这个 NPM 包。 ssh2-sftp-client ssh2-sftp-客户端

const main = () => {
  const servers = ['server list'];
  servers.forEach((s) => {
    const sftp = new Client();
    // Connect to the server
    sftp.connect({
      host: s,
      port: '22',
      username: '',
      password: '',
    }).then(() => logger.log(`Connected to ${s}`))
      // get list of directories
      .then(() => sftp.list(rootLogPath))
      .then((dirs) => {
        dirs.forEach((d) => {
          const target = createTargetDirectory(d.name);
          // list all files in the directory
          sftp.list(`${rootLogPath}/${d.name}`)
            .then((files) => {
              // filter only today's files
              const todayFiles = files.filter((f) => f.type === '-' && moment().format('MMDDYYYY') === moment(f.modifyTime).format('MMDDYYYY'));
              // copy today's files into target
              todayFiles.forEach((f) => {
                sftp.get(`${rootLogPath}/${d.name}/${f.name}`, `${target}/${f.name}`)
                  .then(() => logger.log(`Copied ${f.name} from ${d.name} located on ${s}`));
              });
            });
        });
        return sftp.end();
      })
      .catch(() => logger.log(`Connection to ${s} failed`));
  });
};

main();

The code is working as expected but the problem is I'm not able to terminate the session.代码按预期工作,但问题是我无法终止会话。 The program just waits after its completed the copy files operation.该程序只是在完成复制文件操作后等待。 The sftp.end() call is prematurely closing out connection before copying is complete. sftp.end()调用在复制完成之前提前关闭连接。 If I remove that program just waits after copy is completed.如果我删除该程序,则在复制完成后等待。

I'm not sure where to write the sftp.end() line to terminate the program.我不确定在哪里编写sftp.end()行来终止程序。

EDIT 1: Updated code using Promise.all and making use of async/await now.编辑 1:使用 Promise.all 更新代码并立即使用 async/await。

Split my code into pieces and now making use of async/await for better readability.将我的代码分成几部分,现在使用 async/await 以获得更好的可读性。 Program now ends fine.程序现在结束得很好。 no more waiting or hanging but the problem is files are not copied.不再等待或挂起,但问题是文件没有被复制。 I see a console message "Copied files from source directory".我看到一条控制台消息“从源目录复制文件”。

const copyTodayFiles = async (src) => {
  try {
    let fileList = await sftp.list(`${rootLogPath}/${src}`);
    fileList = fileList.filter(
      (f) => f.type === '-' && moment().format('MMDDYYYY') === moment(f.modifyTime).format('MMDDYYYY'),
    );
    const target = createTargetDirectory(src);

    if (target) {
      fileList.forEach(async (f) => {
        try {
          await sftp.get(`${rootLogPath}/${src}/${f.name}`, `${target}/${f.name}`);
          logger.log(`Copied ${f.name}`);
        } catch (error) {
          logger.log(`Failed to copy ${f.name}`);
        }
      });
      console.log(`Copied files from ${src}`);
    }
  } catch (error) {
    logger.log(`Failed to read files from ${src}`);
    logger.log(error);
  }
};

const workOn = async (server) => {
  sftp = new Client();

  const config = {
    host: server,
    port: '22',
    username: '',
    password: '',
  };

  try {
    await sftp.connect(config);
    logger.log(`Connection to ${server} is successful.`);
    const logDir = await sftp.list(rootLogPath);
    Promise.all(logDir.map((d) => copyTodayFiles(d.name))).then(() => sftp.end());
    // logDir.forEach(async (d) => copyTodayFiles(d.name));
  } catch (error) {
    logger.log(`Connection to ${server} failed.`);
    logger.log(error);
  }
};

const main = () => {
  const servers = ['server list'];
  Promise.all(servers.map((s) => workOn(s)));
};

main();

In short, when you have a "chain" of promises ( a.then(() => b.then(() =>... ) and you want to do something at the end of them, you simply add that thing to the last .then callback.简而言之,当你有一个承诺的“链”( a.then(() => b.then(() =>... )并且你想在它们的末尾做一些事情时,你只需添加那个东西到最后一个.then回调。

However, if you're making multiple promises, you need to wait until all of them are finished, which you can do using Promise.all ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all ):但是,如果您做出多个承诺,则需要等到所有承诺都完成,您可以使用Promise.all ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/参考/Global_Objects/Promise/all ):

Promise.all([promise1, promise2]).then(...

To do that, you'll need to convert all of your forEach calls to instead be map calls, which return the promises they create.为此,您需要将所有forEach调用转换为map调用,后者返回它们创建的 promise。 Once you do that, the map operation will return an array of those promises, which you can use with Promise.all .一旦你这样做了, map操作将返回这些承诺的数组,你可以将其与Promise.all使用。

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

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