【问题标题】:Having difficulty with javascript(node.js) that needs to be synchronous使用需要同步的 javascript(node.js) 有困难
【发布时间】:2021-02-02 01:22:45
【问题描述】:

我有一个 express.js 应用程序,它需要在服务器上运行一个脚本,以便稍后使用函数派生一些值。这是它的要点:

shell.exec(commandString);

readFolder();

renderPage();

基本上,我需要在服务器上运行一个脚本,然后运行第二个函数,然后运行第三个函数。这些需要随后发生,但无论我做什么,似乎javascript都会继续使用第二个和第三个函数。我尝试过承诺、异步、回调。所有这些我只是部分理解并且似乎取得了零进展。

我承认我是一个 javascript 新手。我正在和其他人一起做一个项目,这个任务落到了我身上。我怀疑这是实现我们最终目标的最佳方式,但我别无选择。请帮忙。

我会把整个帖子放在这里供参考:

//Run script when post is rec'd from root and send to results page
app.post("/", (req, res) => {
var commandString;

//take values and create complete command for Astrum script
commandString = 'bash /home/astrum/Main/Astrum.sh -s ' + req.body.speed + ' -h ' + req.body.host + ' -u ' + req.body.username + ' -p ' + req.body.password;

//execute command in shell
shell.exec(commandString);

readFolder();

renderPage();


//Iterate thru filenames to create arrays for links and link labels
function readFolder() {

    fs.readdir('./reports/html/', (err, files) => {
            
        //variable & method for links to html records pages
        ipAddressesLink = files; //this is initialized earlier, globally
        
        //variable and method to remove file extension for link labels in pug
        ipAddresses = files.map(removeExtension); //this is initialized earlier, globally
   
    });

}

//function to remove last five characters of each element
function removeExtension(value) {

    return value.substring(0, value.length - 5);

};

//function to render the page
function renderPage() {

    res.render("results", {ipAddressesLink, ipAddresses, title: 'Results'});

}

res.end();

});

【问题讨论】:

  • shell 来自 shell.js npm 模块

标签: javascript node.js express asynchronous synchronous


【解决方案1】:

这里的 shell 是 child_process 模块吗?如果是,那么您可以传递一个可选的回调参数并从那里调用您的函数。

shell.exec(commandString, (error, stdout, stderr) => {
  const files = readFolder();
  renderPage(files);
});

function readFolder() {
  ...
  return fs.readdirSync(files);
}

function renderPage(files) {
  ...
}

【讨论】:

  • shell 来自 shell.js 模块
  • 从文档来看,exec 函数默认是同步的,尽管回调方法仍然有效。 readFolder 或 renderPage 函数是否执行异步操作?
  • 我的理解是大多数东西默认是异步的; readFolder() 使用 fs.readdir(files) 方法来定义一些先前全局初始化的数组。 renderPage() 将这些数组作为 res.render 方法的一部分发送到视图引擎(pug),用作链接和标签,由 pug 中的 for each 循环创建。我在原始代码中遇到的问题是数组在发送到视图引擎时是未定义的,但如果我第二次尝试则定义;表示第一次跳过某些内容。
  • 是的,fs 上的所有方法默认都是异步的,node 提供了一个类似 fs.readdirSync(file) 的同步版本。您可以切换当前的实现以使用同步方法或使用承诺或回调正确处理异步。编辑答案以反映 readFolder 的实现
【解决方案2】:

你可以这样写:

shell.exec(commandString, (error, stdout, stderr) => {
  // Calling the 1st function after shell command is executed
  readFolder();
});

function readFolder() {
  fs.readdir('./reports/html/', (err, files) => {
    // Some stuff
    ...
    // Calls the 2nd function after fs is done reading files
    renderPage();
  });
}

function renderPage() {
  const options = { ... }; // IP addresses etc.
  res.render(
    "results",
    options,
    // Calls the final function after render is finished
    sendResponse
  );
}

function sendResponse(err, html) {
   // Sends the response. It’s possible that res.send() is the better solution here
   res.end();
}

这只是回调链的一般结构,绝对不是最干净的。如果您想要更好的代码结构和可读性,请尝试切换到async / await 语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多