首页 > 解决方案 > 通过 SSH 使用 exec 的异步等待功能

问题描述

我想通过 SSH 在服务器上连续运行多个功能,一个接一个。我可以为此使用 await/async 函数,但无法让这个示例工作:记录一些文本,运行uptime(等待完成),记录更多文本。

我应该看到输出:

Before await function
STDOUT: (all the uptime info here)
Uptime completed successfully.
After await function

但现在我看到:

Before await function
After await function
STDOUT: (all the uptime info here)
Uptime completed successfully.

在函数完成之前,该函数mainFunction不应打印两个控制台日志。

这是我的例子:

const Client = require('ssh2').Client;

const conn = new Client();

function uptimeFunction() {
  conn.on('ready', function() {
    conn.exec('uptime', function(err, stream) {
      if (err) throw err;

      stream.on('close', function(code, signal) {
        conn.end();

        if (code === 0) {
          console.log('Uptime completed successfully.');
        }
      }).on('data', function(data) {
        console.log('STDOUT: ' + data);
      }).stderr.on('data', function(data) {
        console.log('STDERR: ' + data);
      });
    });
  });

  conn.connect(staging);
};

function awaitFunction() {
  return new Promise((resolve, reject) => {
    resolve(uptimeFunction());
  });
}

async function mainFunction() {
  console.log('Before await function');

  await awaitFunction();

  console.log('After await function');
}

mainFunction();

我已经研究过“ssh2-promise”,但我不明白“exec”的例子会有所帮助。如果我真的需要使用 ssh2-promise,那么这个例子会如何?

我是在做错什么,还是await不能像我想的那样通过 SSH 工作?

谢谢!

标签: javascriptnode.jsasynchronousasync-awaitpromise

解决方案


awaitFunction立即解决并且不依赖于 ssh 的东西。

让我们仔细看看:

return new Promise((resolve, reject) => {
  resolve(uptimeFunction());
});

此承诺将在uptimeFunction执行完成后立即解决。什么时候发生?它在conn.on('ready', function() {完成执行时发生。不幸的是,它只是一个事件绑定。它实际上并没有等待任何东西,从而让承诺解决。

为了解决这个问题,您需要将您的解析功能进一步向下传递。

function uptimeFunction(resolve, reject) {
  conn.on('ready', function() {
    conn.exec('uptime', function(err, stream) {
      if (err) throw err;

      stream.on('close', function(code, signal) {
        conn.end();

        if (code === 0) {
          console.log('Uptime completed successfully.');
          // Success! Resolve.
          resolve();
        } else {
          // Something went wrong, reject promise!
          reject();
        }
      }).on('data', function(data) {
        console.log('STDOUT: ' + data);
      }).stderr.on('data', function(data) {
        console.log('STDERR: ' + data);
      });
    });
  });

  conn.connect(staging);
};


async function awaitFunction() {
  return new Promise((resolve, reject) => {
    uptimeFunction(resolve, reject);
  });
}

推荐阅读