2

Is there a way to do the following without creating an anonymous function 10 times? Assuming setTimeout only takes 2 parameters, the callback and the interval. From what I've heard you shouldn't create functions in a loop since it's slow. However, if an asynchronous function doesn't allow you to pass it the parameters you want the callback to know about, is it possible to avoid doing so? Note: I know in Chrome setTimeout takes more params, so this isn't an ideal example.

function doSomethingAsync(i){
    setTimeout(function() { //This anonymous function is created 10 times
        console.log(i);
    }, 1000);
}

for (var i = 0; i < 10; i++) {
    doSomethingAsync(i);
}
AlexMA
  • 9,842
  • 7
  • 42
  • 64
  • Take a look a [this answer](http://stackoverflow.com/a/8510580/2752041) as it might provide you insights. You could turn parameters into properties of the function object. – mathielo Mar 21 '14 at 19:14
  • @mathielo That is definitely interesting, but it's still not clear to me how to apply that idea (especially since a comment on that answer suggested that you lose the benefit of creating the function once if you go that route). – AlexMA Mar 21 '14 at 19:22
  • Well @AlexMA you could try this [other approach](http://stackoverflow.com/a/7503942/2752041) if you **do not** intend to run your code on IEs. It's not the best solution as it's not completely cross-browser, but in some scenarios it may be helpful. – mathielo Mar 21 '14 at 19:26
  • @mathielo I don't really care about setTimeout, it's just an example of a "restrictive" async function. – AlexMA Mar 21 '14 at 19:31

3 Answers3

2

Short answer - No. Not if you want to match each iteration's value to be mapped back, like you are doing here. I am not going to comment about the performance here, but rather focus on the need first.

If you don't care about the value being mapped to right call, then you can avoid creating functions simply

There are already cases like this that javascript engines allow. That would apply to not having to define multiple anonymous functions. This is achieved by providing more info regarding the current execution to the callback, i.e. an eventobject. This is how DOM, XHRs, HTML5 File APIs, etc., interact back. So this ideally means that something outside the Javascript context is calling a Javascript method with the required info.

The browser or rather the JS engine should provide the mechanism to predefine some sorta eventobject for callback strategy in general, so one function can handle all callbacks. AFAIK, there is no present way to do same in JS itself, apart from creating small function closures. So we gotta wait till there is some news on it.

Hope this helps shed some light on it.

UPDATE - Just saw the note on the question, removing unnecessary code.

aravind
  • 2,867
  • 17
  • 28
1

To give the same result you want, I would go for recursion:

var i = 0; 
doSomethingAsync();
function doSomethingAsync()
{
i = i +1; 
console.log(i);
if (i<10) setTimeout(doSomethingAsync,500);
}
Adel Sal
  • 718
  • 5
  • 16
1

There is one way around this specific example, use eval(). I'm not going to debate whether you should or shouldn't use it, but...

You can rewrite your example like so:

function doSomethingAsync(i){
    setTimeout("console.log(" + i + ");", 1000);
}

for (var i = 0; i < 10; i++) {
    doSomethingAsync(i);
}

Passing a string to setTimeout performs the equivalent of eval() on the string passed in after the time has elapsed.

Preston S
  • 2,751
  • 24
  • 37