简体   繁体   中英

Stop function in node.js with click in frontend

There's a loop that optimizes something in the backend, I want it to go on forever until I hit a stop button in the frontend.

My (simplified) code so far:
On a button press this function is called

function optimize() {    
    $.ajax({
        type: 'GET',
        url: '/optimize',
        success: function (data) {
            updatePlot(data);
        },
    });
}

In the backend:

let optimizingFunction = {};

router.get('/optimize', function (req, res) {
    optimizeFunction(); //This goes on for a long time...
    res.send(optimizingFunction);
});

function optimizeFunction(){
    while(true){
        let betterFunction = {};
        //...
        optimizingFunction = betterFunction;
    }
}

So now how can I stop this function on another button press and get the current optimizingFunction value? - I tried: On a stop-button click

function stop() {    
    $.ajax({
        type: 'GET',
        url: '/stop'
    });
}

Backend:

router.get('/stop', function (req, res) {
    process.exit(1);
});

I noticed it actually executes the stop function but after it executed the first one...
What's an easy 'best practice' approach for problems like this?

So, there are a lot of different ways to go about this. The easiest based on your example is probably to use a setTimeout instead of a loop, and then have some kind of variable you test before deciding to reset the timeout. Something like this (untested):

const app = express(); 

function process() {
  // do work
  if(app.enabled('continue work')) {
    setTimeout(process, 1000); // run every second.  Could set that to smaller intervals
  }
}

app.get('/start', (req, res) => {
  app.enable('continue work');
  process();
  res.sendStatus(200);
});

app.get('/stop', (req, res) => {
  app.disable('continue work');
  res.sendStatus(200);
});

Note, however, this is suboptimal and not very scalable. A better solution would use some kind of work queue or database. Also, you generally don't want to change applications state with GET requests, but use POST or PUT instead.

Adding a more conventional HTTP pattern for doing this kind of work here:

const app = express(); 
const currentState = {}; // this *really* should be in a database for any nontrivial application.

function process() {
  // do work to add properties & values to currentState
  if(app.enabled('continue work')) {
    setTimeout(process, 1000); // run every second.  Could set that to smaller intervals
  }
}

app.post('/start', (req, res) => {
  app.enable('continue work');
  process();
  res.sendStatus(200);
});

app.get('/state', (req, res) => {
  res.send({ state: currentState, processing: app.get('continue work') });
});

app.post('/stop', (req, res) => {
  app.disable('continue work');
  res.send(currentState);
});

Note that a lot of folks don't like URLs as 'actions' (start, stop, etc), but that's mostly preference. Check out articles on REST APIs to understand what that approach looks like, if you care.

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