在收到用户输入之前,我该如何阻止?

时间:2019-01-06 11:04:55

标签: node.js asynchronous user-input blocking

我正在尝试实现以下脚本:

一个函数试图执行一个异步调用,如果引发异常,则提示用户输入该函数是否应该再次运行。

如果用户输入“ y”,则该过程应重复。

如果用户输入“ n”,则该过程应终止。

如果都不是,则该问题应重复。

在用户输入“ y”或“ n”之前,整个脚本的执行都应阻塞。

这是我到目前为止所拥有的(在this answer的帮助下):

async function sendSignedTransaction(rawTransaction) {
    try {
        return await web3.eth.sendSignedTransaction(rawTransaction);
    }
    catch (error) {
        process.stdout.write(error.message + "; try again (y/n)?");
        process.stdin.on("data", async function(data) {
            switch (data.toString().trim()) {
                case "y": return await sendSignedTransaction(rawTransaction);
                case "n": process.exit();
                default : process.stdout.write("try again (y/n)?");
            }
        });            
    }
}

问题是脚本的执行继续进行,而没有等到用户输入“ y”或“ n”。

任何帮助将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:1)

这是因为process.stdin操作也是 异步操作,因此无论您在何处调用初始的sendSignedTransaction,如果引发错误,该代码块中的任何内容(当前)都不会停止该功能退出。

您混合了Promise和经典的回调代码。如果您要确保调用者等到功能完全完成后再进行操作,则可以将完整功能转换为Promise,从而对它进行更多控制,例如

function sendSignedTransaction(rawTransaction) {
  return new Promise(async (resolve, reject) => {
    try {
      const result = await web3.eth.sendSignedTransaction(rawTransaction);
      return resolve(result);
    } catch (e) {
      process.stdout.write(e.message + "; try again (y/n)?");
      process.stdin.on('data', async data => {
        switch (data.toString().trim()) {
          case "y": return resolve(await sendSignedTransaction(rawTransaction));
          case "n": return process.exit();
          default : return process.stdout.write("try again (y/n)?");
        }
      });
    }
  });
}