【问题标题】:Async await function with exec over SSH通过 SSH 使用 exec 的异步等待功能
【发布时间】:2021-03-26 19:33:44
【问题描述】:

我想通过 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 工作?

谢谢!

【问题讨论】:

  • 看起来在awaitFunction 中,你立即用uptimeFunction 的返回值解决了promise,这不是异步的。
  • 知道了。此外,我更新了我的问题以根据需要从 awaitFunction 中删除异步。感谢您的建议!

标签: javascript node.js asynchronous async-await promise


【解决方案1】:

您的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);
  });
}

【讨论】:

  • 我希望看到 uptimeFunction 返回一个承诺。即:以return new Promise((resolve,reject) => { ... 开头,而不是在函数之间拆分模式。但如果你必须,那么至少承认uptimeFunction 已经接受参数(resolve, reject) 所以你可以说return new Promise(uptimeFunction)。并且awaitFunction 不需要声明为async
  • @Wyck OP 的困惑在于回调和承诺如何交互。为了清楚起见,我想最小化 OP 和我的答案之间的差异。 reject 也是有意的,因为错误输出是一种异常状态。
  • 您不太可能希望在收到数据后立即解决。数据是流式传输的,必须累积。解决可能希望在关闭时发生,条件是还积累了有效的数据负载。
  • 你是对的,我错过了close事件。更新了答案。
  • 这行得通!谢谢,我只是在学习 Promise,感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-22
  • 1970-01-01
  • 2020-02-15
  • 2021-10-05
  • 2021-08-23
  • 1970-01-01
相关资源
最近更新 更多