Question

I try to get a function for an asynchronous recursion. In JS this should look like this:

(function asyncRecursion(){
  doStuff();

  setTimeout(asyncRecursion, 1000);
})();

Here's what i've tried in CoffeeScript:

(asyncRecursion = ->
  doStuff()

  setTimeout asyncRecursion, 1000
)()

But this is compiled to:

(asyncRecursion = function(){
  doStuff();

  setTimeout(asyncRecursion, 1000);
})();

and i got an error in JSHint called 'Bad invocation.' for line 1, the asyncRecursion function. So how can i get a JSHint safe asynchronous recursion function. The compiled version works, but there is still that JSHint error. Or should i ignore that 'Bad invocation.' error?

Was it helpful?

Solution

I think JSHint is confused. An assignment is an expression and the value of that expression is the assignment's right hand side; that means that f = function() { ... } is an expression whose value is a function so (f = function() {...})() is perfectly valid JavaScript.

If you ask JSHint about this:

var f;
(f = 11)();

you'll get the same "Bad invocation" error and we see that JSHint probably isn't inferring the type of f, it just doesn't want to you (f = x)() for any x (even when x is definitely a function). I'd tell JSHint to go pound sand and find a better tool. However, if you must use JSHint, you can write your CoffeeScript in two pieces:

asyncRecursion = ->
  doStuff()
  setTimeout asyncRecursion, 1000
asyncRecursion()

and get this JavaScript:

var asyncRecursion;
asyncRecursion = function() {
  doStuff();
  return setTimeout(asyncRecursion, 1000);
};
asyncRecursion();

which JSHint is happy with. Both your original and the "make JSHint happy" version produce the same result when executed.

For extra fun with JSHint's lack of type inference, ask it what it thinks of this:

var asyncRecursion;
asyncRecursion = 11;
asyncRecursion();

OTHER TIPS

You can write it like this:

asyncRecursion = do ->
  doStuff()

  setTimeout asyncRecursion, 1000

It will be compiled into:

var asyncRecursion;

asyncRecursion = (function() {
  doStuff();
  return setTimeout(asyncRecursion, 1000);
})();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top