Search code examples
javascriptnode.jstimer

Pausing/resuming code executing in nodejs


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


Solution

  • 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>