2

I have a javascript question relating to callback and timeout.

This is an example code snippet I wrote:

var f1 = function(){
    var result;
    window.setTimeout(
        function(){
            console.log("timeout in 100ms");
            result = 10;
        }.bind(this), 100);
    return result;
};

So, I want the function to modify the variable result. I used .bind(this) to ensure that it knows what result it.

still, the out put when I run f1() is 9, not 10, which is what I have desired.

Any clues?

Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
MiaoMiao
  • 317
  • 2
  • 7
  • [Why is my variable unaltered after I modify it inside of a function?](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Jonathan Lonowski Jul 13 '16 at 00:34
  • 1
    [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Jonathan Lonowski Jul 13 '16 at 00:36
  • `.bind(this)` has no relevance to variables; that only impacts the value of the `this` keyword. And, your snippet seems to be lacking something if you are at all receiving `9` as a result. – Jonathan Lonowski Jul 13 '16 at 00:37

2 Answers2

4

Result is a number. Therefore it is returned as the value 9 not a reference to an object.

bind does not have any useful effect in your scenario. bind changes the function context (this).

Returning an object containing the value 10 will work.

var f1 = function(){
        var result = { value: 9 };
        window.setTimeout(
                          function(){
                            console.log("timeout in 100ms");
                            result.value = 10;}.bind(this), 100);
        return result;
};

There are likely better solutions to your problem.

Callbacks:

var f1 = function(valueCallback){
        var result;
        window.setTimeout(function(){
            console.log("timeout in 100ms");

            result = 10;
            valueCallback(result);
};

Such a function would be used like so:

f1(function(value)) {
    console.log(value); // Will print 10 after 100ms. 
})

Another alternative, could use Promises:

var f1 = function() {
    return new Promise(function(resolve, reject) {
        window.setTimeout(resolve.bind(null, 10), 100);
    }
}

You would call such a function like so:

f1().then(function(value) {
   console.log(value); // Will print 10 after 100ms.
});
Richard Walton
  • 4,789
  • 3
  • 38
  • 49
  • So, for the solution, value of 9 will be returned initially. If, say, you do var a =f1(), then after 100ms, value of a will be changed to 10. – MiaoMiao Jul 14 '16 at 06:28
  • Ah, thanks. I didn't know that Promise is standard Javascript, always assumed that it's part of a package. That was helpful, thanks! – MiaoMiao Jul 14 '16 at 21:10
0

You are calling the timeout to modify the value after the function already returned, so it returns the default value for result, then call the timeout, and since the value is limited in scope to the function, you have no means to return it after modification.

What you can do is this

var result = 9;
var f1 = function(){

            window.setTimeout(
                              function(){
                                console.log("timeout in 100ms");
                                result = 10;}.bind(this), 100);
            return result;};

And then after calling f1 t will return 9 then call result and it will show 10

MoustafaS
  • 1,991
  • 11
  • 20