2

In the code below I would expect two 4 second delays. But if you run the code you will see it executes instantly. Obviously I don't understand something very fundamental or I am a stupid error I can't see.

function calculatesomething(resolve) {
  console.log("calculating");

  setTimeout(results(resolve,3),4000);
}

var answer=0;
function results(resolve,n) {
  console.log("got results");

  answer=1;
  resolve(answer+n);
}



function doingstuff() {
  console.log("starting");

  var promise1 = new Promise(function(resolve) {
    setTimeout(calculatesomething(resolve),4000);
  });

  promise1.then(function(value) {
    console.log("done: "+value);
  });

  console.log("regular execution");
}

doingstuff();

(sorry about the indenting here. I have no idea why its not respecting the tabs.)

Tim Han
  • 168
  • 1
  • 12
user1254723
  • 141
  • 8

2 Answers2

6

The very fundamental thing is this:

 setTimeout(results(resolve,3),4000);

You dont need to call the function directly and pass the returned value, but rather pass the function reference:

 setTimeout(results, 4000, /*args:*/ resolve, 4);
Jonas Wilms
  • 106,571
  • 13
  • 98
  • 120
  • 1
    TIL you can pass the parameters in with `setTimeout`. – Derek 朕會功夫 Feb 14 '18 at 20:18
  • Pretty elegant solution, upvote – Commercial Suicide Feb 14 '18 at 20:23
  • @derek just spent 10 minutes each in writing [this](https://stackoverflow.com/questions/48780927/javascript-when-and-when-not-to-use-this/48790252#48790252) and [this](https://stackoverflow.com/questions/48794471/general-solution-for-pre-emptive-background-work-scheduling-on-javascript/48795175#48795175) answer and i get 5 upvotes for such a common mistake, that is well documented everywhere... :/ And you didnt know this? That surprises me... – Jonas Wilms Feb 14 '18 at 20:26
  • @commercial suicide thanks :) – Jonas Wilms Feb 14 '18 at 20:26
  • @JonasW. Even as an experienced developer, JavaScript still gives me surprises every now and then ;) – Derek 朕會功夫 Feb 14 '18 at 21:29
1

setTimeout accepts a callback function as first parameter and one of possible solutions will be to wrap your function invocation inside an anonymous function like this:

function calculatesomething(resolve) {
  console.log("calculating");

  setTimeout(function() {
    results(resolve,3);
  }, 4000)
}

var answer=0;
function results(resolve,n) {
  console.log("got results");

  answer=1;
  resolve(answer+n);
}



function doingstuff() {
  console.log("starting");

  var promise1 = new Promise(function(resolve) {
    setTimeout(function() {
      calculatesomething(resolve)
    }, 4000);
  });

  promise1.then(function(value) {
    console.log("done: "+value);
  });
        
  console.log("regular execution");
}

doingstuff();
Commercial Suicide
  • 13,616
  • 13
  • 48
  • 72