简体   繁体   中英

Randomly generated numbers won't change when I refresh website. I'm using JavaScript and NodeJS

when I generate random numbers with JavaScript language (using Node JS) when I refresh the page, the random numbers don't change, the only way to change them is for me to restart the server. Here is the code snippet.

'''
const random = Math.round(Math.random() * 1);

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

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

///////////

app.get("/", function(request, response) {
  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("/");
});
'''

You're currently only generating your random numbers when the server initially starts up, which happens once, not every time the page loads. When your server initially starts, it registers routes for GET and POST requests. When you search for a URL in your search bar, you're performing a HTTP GET request to a specific path. In your case, if that path matches / the callback for your .get('/', <callback>) will be invoked.

This means that if you want a particular action to occur when you visit your site, you'll need to put your logic in this callback (or add it as middleware). Currently, you're rendering your page and sending that back to the client's browser to be viewed as HTML. However, you can do more than just this, such as generate your random numbers:

app.get("/", function(request, response) { // Invoked when get request is sent to the path `/`
   /*
     Add random number logic here which calculates:
     `firstNumber`, `secondNumber`, `randomOperation` and `result`.
   */
  response.render("index.ejs", {
    firstNumber: firstNumber,
    secondNumber: secondNumber,
    randomOperation: randomOperation,
    result: result
  });
});

Side notes:

Your code could also do with a little refactoring. Currently your firstNumber and secondNumber repeat the same code, this could be decomposed into a function:

function getRandNumber(random) {
  return random ? (Math.random() * (10000) - 5000).toFixed(2) : (Math.round(Math.random() * (100)) - 50);
}

Or, if you prefer, you can use an arrow function instead:

const getRandomNumber = random => random ? (Math.random() * (10000) - 5000).toFixed(2) : (Math.round(Math.random() * (100)) - 50);

Using eval() is often frowned upon , and there is usually a way to avoid using it. Since you have a fixed number of operations, you can define an object which keeps keys as the operation strings, and values as functions which perform that operation between two input numbers:

const operationsMap = {
  '+': (x, y) => x + y,
  '-': (x, y) => x - y,
  '/': (x, y) => x / y,
  '*': (x, y) => x * y
};

Now if you do operationsMap['+'] , you will get the function (x, y) => x + y , which you can then call to get the answer for adding two numbers x and y .

So, refactoring your code a little, you can make it look like;

// Objects and functions which live outside of your `.get()`
const operationsMap = {
  '+': (x, y) => x + y,
  '-': (x, y) => x - y,
  '/': (x, y) => x / y,
  '*': (x, y) => x * y
};
const getRandomNumber = random => random ? (Math.random() * (10000) - 5000).toFixed(2) : (Math.round(Math.random() * (100)) - 50);

// Code for computing random numbers (could be in its own function and called inside the `.get()` callback function)
const random = Math.round(Math.random() * 1);
const firstNumber = getRandomNumber(random);
const secondNumber = getRandomNumber(random);
const operations = random ? ["+", "-"] : ["*", "/"];

const randomOperation = operations[Math.round(Math.random() * 1)];
const resultNumber = operationsMap[randomOperation](firstNumber, secondNumber);
const result = resultNumber.toFixed(2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM