简体   繁体   中英

Javascript : setTimeout use on an anonymous function expression

I recently started learning javascript to help maintain some stuff and ran into this issue today:

this.moveChar = function(){  
    // body here
    setTimeout(moveChar,1000);
}

this.initialise= function(){
    this.moveChar();
}

When initialise is called, I expected moveChar to be called, then repeated call itself once every 1000ms

However, what actually happens is moveChar gets called once then that's it. Based on other stackoverflow posts I read, I suspected it might be something to do with the function being expressed rather than declared. I have tried to use

this.moveChar = function recMove(){  
    // body here
    setTimeout(recMove,1000);
}

without luck either.

Any suggestions on how I can fix this?

EDIT: Main thing I need to do is have the moveChar function called once every second. If there is a better approach than setTimeout recursion, I'm open to it

this.moveChar is not the same as moveChar , unless this is the global scope object like window .

this.moveChar is a property on an object, while moveChar would reference any variable in a visible scope chain.

You can change it to a couple of things in order to keep scope of whatever object is being used:

Using an arrow function

this.moveChar = function(){  
    // body here
    setTimeout(()=>this.moveChar(),1000);
}

Using .bind()

this.moveChar = function(){  
    // body here
    setTimeout(this.moveChar.bind(this),1000);
}

Are you using this in side body here?
If so, you should bind correct context while call.

this.moveChar = function(){  
    // body here
    setTimeout(this.moveChar.bind(this), 1000);
}

Or use anonymous function:

this.moveChar = function(){  
    // body here
    var that = this;
    setTimeout(function(){
      that.moveChar();
    }, 1000);
}

Or arrow function:

this.moveChar = function(){  
    // body here
    setTimeout(() => this.moveChar(), 1000);
}

Same notes apply to setInterval variant:

this.initialise= function(){
   setInterval(this.moveChar.bind(this), 1000);
   // var that = this;
   // setInterval(function(){that.moveChar();}, 1000);

   // setInterval(() => this.moveChar(), 1000);
}

You might want to consider using setInterval() which is the more appropriate API for this task.

What setInterval() does is - it will repeatedly call the given function upon a certain interval is reached.

See: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval

Quote:

Repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. Returns an intervalID.

Example:

Assuming moveChar() contains your operation logic. Then to repeat it you'll do this 1 line.

let moveChar = function(){  
    // Do stuff
    console.log("Hi thanks for calling me!");
}

setInterval(moveChar, 1000);
   this.moveChar = function(){  
       // body here
     alert('called moveChar');
  }

this.initialise= function(){
     setInterval(function(){moveChar();},1000);
}

 this.initialise();//call here

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