【问题标题】:I can't call a function created inside another function using Node.JS我无法使用 Node.JS 调用在另一个函数中创建的函数
【发布时间】:2020-07-28 09:37:02
【问题描述】:

我对这段代码的目标:这段代码应该随机生成一个数学方程,用户应该在其中输入结果(用户认为正确的结果)。然后计算机应将用户输入的输入(结果)与真实结果进行比较。如果结果正确,它应该控制台日志(“好”),如果它不正确,它应该控制台日志(“坏”),无论哪种方式,点击提交按钮后,网站应该刷新并随机生成一个新方程(并且这个过程会再次重复)。

问题:我有函数equationGenerator,它生成随机方程并计算结果。我需要在 node.js 的 app.get 函数中调用 equationGenerator 以便每次刷新网站时都会出现一个新函数,不幸的是该函数没有被调用,我现在在尝试加载网站时遇到错误.

代码如下:

////Installations (not the actual code)

const bodyParser = require("body-parser");
const express = require("express");
const ejs = require("ejs");

const app = express();

app.set('view engine', 'ejs');

app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));


 ////The actual code

function equationGenerator(){

 var random = Math.round(Math.random() * 1);

 var firstNumber = random ? (Math.random() * (10000) - 5000).toFixed(2) : (Math.round(Math.random() * (100)) - 50);
 var secondNumber = random ? (Math.random() * (10000) - 5000).toFixed(2) : (Math.round(Math.random() * (100)) - 50);
 var operations = random ? ["+", "-"] : ["*", "/"];

 var randomOperation = operations[Math.round(Math.random() * 1)];
 var expression = firstNumber + randomOperation + secondNumber;
 var resultNotInterger = eval(expression);
 var result = Number(resultNotInterger).toFixed(2);

 return {
  firstNumber,
  secondNumber,
  randomOperation,
  result,
 };
}



app.get("/", function(request, response){
 equationGenerator()
 response.render("index.ejs", {
 firstNumber: firstNumber,
 secondNumber: secondNumber,
 randomOperation: randomOperation,
 result: result
 });
});

app.post("/", function(request, response){
 const clientResponse = Number(request.body.clientResponse).toFixed(2);
 if (clientResponse === result){
    console.log("Good");
    }else{
    console.log("Bad");
    }
response.redirect("/");
});

/////Server start code

app.listen(2109, function(err){
if (err){
console.log(err + "JHGKGFKUYGLUYFLIFYGUFYOIY:GYP");
}else{
console.log("Running on port 2109");
 }
});

这里是 ejs 代码:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Math Ecercise</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1>Math</h1>
<p><%= firstNumber %> <%= randomOperation %> <%= secondNumber %> = <%= 
result %></p>
<form class="" action="/" method="post">
   <div class="lediv">
  <input class="form-control" type="text" name="clientResponse" value="" placeholder="result" autocomplete="off">
  <button class="btn btn-primary btn-info" type="submit" name="button">Submit</button>
  </div>
  <p class="message">Haha</p>
</form>
</body>
</html>

如果您有任何困惑,我将非常乐意回答任何问题,因为我已经尝试解决这个问题好几天了。

非常感谢!

这里是下载到 wetransfer 中完整文件的链接 - https://wetransfer.com/downloads/8f193e12b9505c086728d3d5e976e11f20200728000447/51fde6。确保您使用 app1.1.js 进行尝试。我有很多版本,但这是当前版本。

如果您有任何困惑,我将非常乐意回答任何问题,因为我已经尝试解决这个问题好几天了。

非常感谢!

【问题讨论】:

  • equationGenerator` 返回一个对象,但你不使用它。
  • 我想将来自equationGenerator'的数据传输到里面的对象:response.render(比如firstNumber),这个在app.get里面。
  • 所以你引用了返回的对象const eg = equationGenerator(); console.log(eg.firstNumber);
  • @epascarello 是的,我确实想使用 app.get 中的对象,因为我希望它出现在我的 index.ejs 文件中
  • @ggorlen 我刚刚更新了问题,您需要帮助我,我还提供了文件的下载链接,谢谢提醒。

标签: javascript node.js ejs


【解决方案1】:
app.get("/", function(request, response){
 equationGenerator()
 response.render("index.ejs", {
 firstNumber: firstNumber,
 secondNumber: secondNumber,
 randomOperation: randomOperation,
 result: result
 });
});

你没有使用 equationGenerator() 的返回值。

尝试以下方法:

app.get("/", function(request, response){
 response.render("index.ejs", equationGenerator());
});

【讨论】:

  • 嘿,谢谢你的回答,它不适合我,一旦我刷新页面我就会得到错误,有什么办法解决这个问题?
  • 是的,对不起,错误只是说“结果未定义”
【解决方案2】:

equationGenerator() 返回一个对象,并且您没有将该对象分配给任何东西,因此它只是丢失了。由于返回的对象与您要传递的 response.render() 完全匹配,因此您可以直接传递它:

app.get("/", function(request, response){
 const data = equationGenerator()
 response.render("index.ejs", data);
});

或者,甚至只是:

app.get("/", function(request, response){
 response.render("index.ejs", equationGenerator());
});

如果返回的对象与您要传递的对象不完全匹配,那么您可以将对象分配给一个变量并挑选出您要传递的对象的片段:

app.get("/", function(request, response){
 const data = equationGenerator()
 response.render("index.ejs", {
     firstNumber: data.firstNumber, 
     secondNumber: data.secondNumber,
     randomOperation: data.randomOperation,
     result: data.result
 });
});

或者,您可以使用解构赋值来完成同样的任务,方法是分配给局部变量,然后使用这些值构建一个新对象:

app.get("/", function(request, response){
 const {
     firstNumber,
     secondNumber,
     randomOperation,
     result
 } = equationGenerator();

 response.render("index.ejs", {
     firstNumber, 
     secondNumber,
     randomOperation,
     result
 });
});

显然,由于返回的数据对象已经是你想要传递给res.render()的数据,所以上面的第一个选项是最简单的。


问题的第二部分(以 cmets 为单位)关于在表单发布时比较结果

OP 想知道如何在生成页面时“保存”result,以便以后在提交包含用户条目的表单时将其与提交的结果进行比较。

通常需要无状态解决方案(不跨请求在服务器上存储中间状态)(如果可行)。我可以想到两种无状态的解决方案。

  1. 将输入数据与表单提交一起放入(作为隐藏字段,以便在提交表单时将它们发送回服务器)并在提交表单时在服务器上计算所需的结果。然后,您可以将用户结果与服务器计算的结果进行比较,无需将预先计算的结果“保存”到任何地方。

  2. 继续像你一样计算结果,但加密结果并将其放入表单(作为隐藏字段),以便将其连同答案一起提交回服务器。然后,当您收到 POST 表单时,解密 result 并与用户的结果进行检查。

也有非无状态的解决方案。您可以为每个问题页面生成一个随机表单 ID,并将其作为隐藏字段嵌入表单中,以便将其与表单一起提交回来。然后,您可以使用express-session 来保存用户状态。在该用户状态中可能是一个 Map 对象,其中包含 formID,result 的键、值对。提交表单时,您从表单中获取 formID,在用户的会话对象中查找预期结果,然后将提交的结果与预期结果进行比较。您需要一些方案来老化用户从未使用过的会话对象中的 formID(因为他们从未提交过表单,或者因为他们多次点击刷新生成一堆他们从未使用过的 formID)。

【讨论】:

  • 对不起,给我几秒钟,我正在查看答案并尝试一下,顺便谢谢。不过,我想确保它与我的 ejs 元素兼容。
  • 嘿,感谢所有的努力,不幸的是代码不断产生错误。我在我的问题中添加了更多信息,甚至还添加了文件的下载链接,app1.1.js 是我正在使用的文件,如果你愿意,可以看看(我使用 Atom 编辑器)。
  • @WiseEye - 当你只是说“不断产生错误”时,它不是很有帮助。我们需要确切地知道什么错误(确切的错误文本)并确切地知道错误来自什么代码。这是基本调试。我不会检查你的整个项目并试图找出可能导致错误的原因。您需要向我们展示确切的错误和导致该错误的代码,然后我们可以帮助诊断可能导致该错误的原因。我已经向您展示了如何修复您最初发布的错误,该错误将数据正确传递到您的模板。
  • 对不起,你是对的。它显示的错误是“ReferenceError: result is not defined”
  • @WiseEye - 而且,该错误发生在哪一行代码上?什么是堆栈跟踪?
猜你喜欢
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多