Home > front end >  Async await not working as I expected on emitter
Async await not working as I expected on emitter

Time:09-09

I'm trying to learn by building a simple game with html and Js, using Nodejs and mongoose on the backend. It is like a grid where you can click to move around and you have to get to the treasure. When you click in the treasure tile, the backend gets the wincode from Mongodb and send it to the front.

miApp.allGames is an array where I store a "currentUserInfoMov" obcject with the info for every game currently being played, one for browser using local storage, that is working fine.

My problem is that movementsEmitter don't wait until it gets the code from Mongodb. In my console I can see the console.logs in this order:

1.you win!
2. Sent to front
3. Emitter finished

routerApi.post("/clicked", async (req, res) => {
  try {
    miApp.movementsEmitter.emit("playerWantToMove", req.body, grid);
    const currentUserInfoMov = miApp.allGames.filter(x => x.Id == req.body.id)[0];
    res.send(currentUserInfoMov);
    console.log("Sent to Front");

  } catch (error) {
  console.log(error)  
  }
})

On the movementsEmitter:

movementsEmitter.on("playerWantToMove", async (tileClickedAndId, grid) => {

...more code here working fine...

 if (playerDestiny == treasureTile) {
  console.log("you win!");
  const bottle = await Bottles.findById(BOTTLEID);
  currentUserInfoMov.winCode = bottle.codeToWin;     
  TakeBottle();
  console.log("Emitter finished");
     
}
}

CodePudding user response:

Based on your code, everything is happening as expected.

  1. you are emitting the playerWantToMove event
  2. The on event handler is called => and console.log("you win!") is called
  3. You await a request to Bottles. This is an asynchronous request and gets moved to the job queue, until the call stack is empty.
  4. The code then the continues to execute your .post block => and console.log('sent to front') is called
  5. the call stack is now empty, so the code below the awaited line runs => and console.log(Emitter finished) is called

So you need to reorder your code a bit. If you want to execute in a different order, just move the emit to after res.send. My guess though, is that takeBottle updates the DB and therefore the response you are sending to the front end. You can try to await the emitted event (if your event emitter allows that. await miApp.movementsEmitter.emit("playerWantToMove", ...). The other option is update the event handler to call res.send() within that, after TakeBottle() is called

  • Related