Contexte

Je crée une application Node.js qui génère un nombre aléatoire toutes les 6 secondes et la rend disponible via une API.

Pour garder la logique de génération de nombres hors du fichier API, j'ai encapsulé dans une fonction appelée numberGen, dans un autre fichier.

api.js

const express = require("express");
const numberFactory = require("../numberGen.js");

module.exports = (function() {
    let interval = 6, min = 0, max = 100;

    const api = express.Router();
    const numberGen = numberFactory({
        interval, min, max
    });
    numberGen.run();

    api.get("/Numbers/", (req, res) => {
        res.json({ random: numberGen.currNum});       
    });

    return api;
})();

numberGen.js

"use strict";

module.exports = function(args) {
    let {
        interval,
        min,
        max
    } = args;

    let currNumber = genRandom(min, max);

    function run() {
        setTimeout(() => {
            currNumber = genRandom(min, max);
            run();
        }, interval);
    }

    function genRandom(min, max){
        return Math.floor(Math.random() * max) + min;
    }

    return {
        interval, currNumber,
        run
    };
};

Idéalement, un client fait une requête à 0 seconde, obtiendrait le numéro X, et faisant la même requête 6 secondes après, obtiendrait un chiffre Y, car le serveur génère un nouveau nombre aléatoire toutes les 6 secondes.

Problème

Le problème ici est que le client obtient toujours le même numéro, quoi qu'il arrive.

Tentatives

Au début, je pensais que cela se produisait parce que numberGen renvoie un objet qui ne change jamais. Pour résoudre ce problème, j'ai essayé de passer un numéro du api.js au générateur à mettre à jour, mais cela n'a pas fonctionné non plus car le client reçoit toujours un objet vide, car serverNum === undefined;

numberGen.js

"use strict";

module.exports = function(args) {
    let {
        interval,
        min,
        max,
        serverNum
    } = args;

    serverNum = genRandom(min, max);

    function run() {
        setTimeout(() => {
            serverNum= genRandom(min, max);
            run();
        }, interval);
    }

    function genRandom(min, max){
        return Math.floor(Math.random() * max) + min;
    }

    return {
        interval,
        run
    };
};

api.js

const express = require("express");
const numberFactory = require("../numberGen.js");

module.exports = (function() {
    let interval = 6, min = 0, max = 100, serverNum;

    const api = express.Router();
    const numberGen = numberFactory({
        interval, min, max, serverNum
    });
    numberGen.run();

    api.get("/Numbers/", (req, res) => {
        res.json({ random: serverNum});       
    });

    return api;
})();

Question

Étant donné que je veux garder cette logique séparée du fichier api.js, comment puis-je corriger mon code?

0
Flame_Phoenix 3 avril 2017 à 16:13

2 réponses

Meilleure réponse

L'objet que vous renvoyez contient la valeur de currNumber à ce moment précis - pas une référence. Ajoutez une fonction qui renvoie la valeur actuelle réelle du nombre et appelez-la au lieu de numberGen.currNum.

numberGen.js

module.exports = function(args) {
  // add this function
  function getNumber() {
    return currNumber;
  }
}

api.js

api.get("/Numbers/", (req, res) => {
    res.json({ random: numberGen.getNumber()});       
});
4
Kaivosukeltaja 3 avril 2017 à 13:26

Ou vous pouvez simplifier votre code pour api.js

const express = require("express");


module.exports = (function() {
let interval = 6, min = 0, max = 100, serverNum;

const api = express.Router();
function genRandom(min, max){
    return Math.floor(Math.random() * max) + min;
}

setInterval(function () {
    serverNum=genRandom(min,max)
    console.log(serverNum);
}, 6000);

api.get("/Numbers/", (req, res) => {
    res.json({ random: serverNum});
});

return api;
})();
0
Johan Willfred 3 avril 2017 à 13:32