1

So i am making some kind of game, where a player has some powerups. After the players turn is over, there should be a 5 sec timeout in the server, where no code is executed, and then the turn should be passed after the time. However if the client clicks in one of the powerups, the server should stop the 5 second timeout and start executing again. How do i implement this?

Currently i am using,

await new Promise(r => setTimeout(r, 5000))

which stops and waits for the timeout to end, but how can I stop the timeout when the client selects a powerUp? How do we clear Promise based timeout?

To be short what i want to do is:

server side code

function doSomething(){
     if(playerHasPowerUps) await new Promise(r => setTimeout(r, 5000))
     //do other things
}

in client side in this period if the player clicks on a powerup, it informs the server about the event and the server is meant to stop the above timeout and do other things

Ashok
  • 369
  • 5
  • 16
  • You haven't provided much code context here to advise very specifically, but you can have another part of your code that resolves the promise earlier (before the timeout fires) if a powerup is clicked. – jfriend00 Oct 31 '19 at 03:33
  • So can i just store above promise in a variable? How do i resolve the promise from somewhere else? Also i have edited the description, can you see if you can help me? – Ashok Oct 31 '19 at 03:45
  • You don't show how this code gets notified that a powerup has been clicked. That determines what options you might have. In general, one would not need to resolve a promise outside of the promise executor, but you can do it with a Deferred object design pattern you can see here: https://stackoverflow.com/questions/37651780/why-does-the-promise-constructor-need-an-executor/37673534#37673534 – jfriend00 Oct 31 '19 at 04:05

1 Answers1

2

My solution to this will be creating a class that manages Promise and Timeout instances.

Let's name this class Sleep, it takes duration in its constructor and schedule timeout upon the given duration as well as creating a promise instance.

Add an async function wait() which returns the promise instance so that we can await on.

Add a function cancel() which simply resolve the promise instance and clear timeout.

<html>
 <body>
  <button onClick="cancelWait()">Cancel wait</button>
  <div id="text"></div>
 </body>

 <script lang="javascript">

  class Sleep {
     constructor(duration) {
     this.promise = new Promise((resolve) => {
    this.promiseResolve = resolve
    this.timeout = setTimeout(() => {
      resolve()
    }, duration)
     })
     }
     
     async wait() {
     return await this.promise
     }
     
     cancel() {
     clearTimeout(this.timeout)
     this.promiseResolve()
     }
  }

  //Usage
  let sleep
  
  const main = async () => {
   const text = document.getElementById("text")
   text.innerText = 'start'   
      
   sleep = new Sleep(3000)
   await sleep.wait() 

   text.innerText = 'finish'
  }
  
  const cancelWait = () => {
   sleep.cancel()
  }
  
  main()

 </script>

</html>
Plus Pingya
  • 171
  • 8
  • cheers! it worked. Can you suggest me some website/video where i can learn more of this stuff? – Ashok Oct 31 '19 at 06:22
  • @Ashok You already know about [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) and [setTimeout](https://www.w3schools.com/jsref/met_win_settimeout.asp), now you've just seen me using [clearTimeout](https://www.w3schools.com/jsref/met_win_cleartimeout.asp) and [JavaScript class](https://www.w3schools.com/js/js_classes.asp). These are 4 stuff put together to achieve what you want. Not sure if there's websites teaching this. Just looking at their docs, you'll learn them by using them over and over and by times, you will gain comprehension. – Plus Pingya Oct 31 '19 at 06:54