0

I'm new to asynchronous javascript. I realise that code A works the same as code B.

Code A:

const name = ['a','b','c'];
setTimeout(()=>{
   console.log(name);
},1500)

Code B:

const name = ['a','b','c'];
setTimeout(list=>{
   console.log(list);
},1500,name)
  1. Should we go with Code A or Code B, which is better in terms of asynchronous?
  2. If we can use the variables that are declared outside setTimeout() directly in the setTimeout(), Why should we passing them into setTimeout() as third or fourth, etc parameters?
LittleTeemo
  • 184
  • 2
  • 12
  • 2
    The latter case is mostly superfluous. If you are going to use `setTimeout` itself to pass the parameters, you may as well do `setTimeout(console.log, 1500, name)`. – VLAZ Jul 23 '20 at 06:18
  • 1
    Answer to 1. - neither. They are mostly the same. At best the Code A can protect from [losing the correct `this`](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback/) but it's not always needed. The latter is shorter and can be easier to read in some cases. – VLAZ Jul 23 '20 at 06:19
  • As for 2. there is a difference in some cases, compare `foo = 1; setTimeout(() => foo = 42, 100); setTimeout(() => console.log(foo), 500);` with `foo = 1; setTimeout(() => foo = 42, 100); setTimeout(console.log, 500, foo);` – VLAZ Jul 23 '20 at 06:22

2 Answers2

1

The reason you might want to pass in parameters is that they are passed with what they are at the time you create the timeout. Consider for example these examples:

const name = ['a','b','c'];

let i = 0;
while (i < name.length) {
    setTimeout(function(letter1) {
        console.log({letter1});
    }, i * 100, name[i]);
    
    setTimeout(function() {
        console.log({letter2: name[i], i});
    }, i * 1000);
    i++;
}

Without passing in the arguments, by the time the setTimeout function runs, i is already 3, so you get undefined for every console.log

dave
  • 62,300
  • 5
  • 72
  • 93
  • It's only true for primitives, if you pass an object it will change (the content of it). – cy3er Jul 23 '20 at 06:29
  • 2
    That's… constructed. With `for (let i=0; i – Bergi Jul 23 '20 at 06:30
  • @cy3er the difference isn't "primitives vs objects" - it's whether the variable is reassigned or not. [See here](https://jsbin.com/ruyutus/edit?js,console) – VLAZ Jul 23 '20 at 06:34
0

You should go with code B, Just to add explanation

(function () {
    const name = ['a','b','c'];
const name2 = [1,2,3];

    setTimeout((test)=>{
       console.log(test, name2); // here I am printing test, which is passed as arguments.
    },1500, name);
})();

so here to access that inside the setTimeout you have to add parameters in your function definition, otherwise this is reading similar name from it's parent scope, like name2 in this example's case.

Anks
  • 101
  • 1
  • 6
  • So, why exactly is B better? The two would work the same *in this case*. That's not always going to be the same, however - if you want to print the assigned value of the variable *at the time of printing*, then passing the variable via `setTimeout` will not work, since it will give you the value *at the time of calling `setTimeout`. [See here](https://jsbin.com/ruyutus/edit?js,console) for some examples how this can differ - specifically `foo` and `bar`. – VLAZ Jul 23 '20 at 06:45
  • 1
    You have shown the one version here that I would discourage: using setTimeout to pass the arguments into an anonamous function. That way youre just confusing whoever is going to read this code as to where anything comes from. Either use an anonamous function with a closure `var foo=...; setTimeout(() => { /* use foo */ }, 1500);` or pass a callback function and the args to setTimeout, like `setTimeout(callback, 1500, ...argsForCallback);` – Thomas Jul 23 '20 at 07:02