1

In the following code, I want to get a Grid, ask for x and y. Then I'll get the Grid again.

However, due to Node.JS being asynchronous, the second get gets executed after asking for x, before x is given and before y is asked.

I should probably check if the earlier process has finished before executing the rest of the code. This is usually done by a callback, as far as I know. My current callback seems insufficient, how do I force synchronous execution in this case?

I've tried to keep it MCVE, but I didn't want to leave anything essential out either.

"use strict";
function Grid(x, y) {
  var iRow, iColumn, rRow;
  this.cells = [];
  for(iRow = 0 ; iRow < x ; iRow++) {
    rRow = [];
    for(iColumn = 0 ; iColumn < y ; iColumn++) {
      rRow.push(" ");
    }
    this.cells.push(rRow);
  }
}

Grid.prototype.mark = function(x, y) {
  this.cells[x][y] = "M";
};

Grid.prototype.get = function() {
  console.log(this.cells);
  console.log('\n');
}


Grid.prototype.ask = function(question, format, callback) {
 var stdin = process.stdin, stdout = process.stdout;

 stdin.resume();
 stdout.write(question + ": ");

 stdin.once('data', function(data) {
   data = data.toString().trim();

   if (format.test(data)) {
     callback(data);
   } else {
     stdout.write("Invalid");
     ask(question, format, callback);
   }
 });
}

var target = new Grid(5,5);

target.get();

target.ask("X", /.+/, function(x){
  target.ask("Y", /.+/, function(y){
    target.mark(x,y);
    process.exit();
  });
});

target.get();
4
  • You cannot force synchronous execution. You can make execution sequential though (while still being asynchronous). Just move your second target.get() call right before your second target.ask(…) call - inside the first callback. Commented May 9, 2015 at 20:06
  • @Bergi Now the second target.get() will be executed after x is being put in but still before y is asked. It's better than it was, but y is required before the second target.get() is executed. Commented May 9, 2015 at 20:16
  • Oh right, I didn't really get what you wanted. It seems like you want to put it right after the target.mark(x, y) call then. Commented May 9, 2015 at 20:19
  • @Bergi That's it :) Feel free to make it an answer. Commented May 9, 2015 at 20:24

1 Answer 1

1

how do I force synchronous execution?

You cannot force synchronous execution. You can make execution sequential though (while still being asynchronous) by moving the code that you expect to be executed after the async action inside the callback (which is called back asynchronously).

In your case, you seem to be looking for

var target = new Grid(5,5);
target.get();
// executed before the questions are asked
target.ask("X", /.+/, function(x){
  // executed when the first question was answered
  target.ask("Y", /.+/, function(y){
    // executed when the second question was answered
    target.mark(x,y);
    target.get();
    process.exit();
  });
});
// executed after the first question was *asked*
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.