0

I'm just trying to return a value after a delay but all I get is the number 1. If I call the same function again, I get 2, 3, 4, etc so I've made a weird counter but not what I wanted!

let wait = n => setTimeout(_ => n, n*1000);
console.log(wait(5));

I've tried all the variations I can think of. Is this some kind of scope problem?

Any ideas?

Sab
  • 63
  • 2
  • 3
  • 6
    Your function is returning the value returned by `setTimeout` which is an identifier of the timeout (an integer), not `n`. If you want to get the `n` value back you need to use an async pattern like a callback or promise. – Mark Jan 07 '18 at 19:09
  • Related: [*How to make a promise from setTimeout*](https://stackoverflow.com/questions/22707475/how-to-make-a-promise-from-settimeout) – T.J. Crowder Jan 07 '18 at 19:17

1 Answers1

2

You're returning n from the callback you pass to setTimeout - not the outside function. In actuality, your wait function returns a ID of a timeout returned from setTimeout. The only way you can really "delay returning" is to use a Promise and resolve after a timeout:

const wait = n => new Promise(resolve => setTimeout(() => resolve(n), n * 1000));

Then:

wait(5).then(n => console.log(n)) //5

Then wait returns a Promise that resolves in 5 seconds to n which you can access via Promise#then. With promises, you can also utilize async and await from ES2016 to get a closer result to what you want:

const wait = n => new Promise(resolve => setTimeout(() => resolve(n), n * 1000));

(async () => {
  console.log(await wait(5));
})();

What await does is await for a promise to resolve. So await wait(5) waits for the promise returned from wait to resolve (which is after 5 seconds). Then, it logs the resolved value. You'll also notice it's wrapped in an async immediately executes arrow function. To use await you need to be in an async function.

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
  • Nice answer (unsurprisingly). I've deleted mine, the above is good and mine mostly duplicated it (unintentionally, but the result is the same). Feel free to grab the async/await stuff (copy and paste if you like) since I know you can see deleted answers. :-) – T.J. Crowder Jan 07 '18 at 19:22
  • @T.J.Crowder Thanks! I completely forgot about that duplicate. – Andrew Li Jan 07 '18 at 19:30
  • Sorry, I meant my answer here duplicated your answer here, not my answer to the related question (nor to the dupetarget). Bergi's pick of a dupetarget is...interesting. A stretch in my view, but it's a matter of degrees, not a matter of kind. (I don't remember voting to close the question, but apparently I did. I wonder what reason I picked.) – T.J. Crowder Jan 07 '18 at 19:34
  • @T.J.Crowder I understand, I just forgot the dupe target and should've hammered. – Andrew Li Jan 07 '18 at 19:35
  • It's all well-intentioned, which is the main thing. – T.J. Crowder Jan 07 '18 at 19:36
  • @T.J.Crowder thank you for your replies. I thought It might come down to promises. I was just looking to test a memoize function and all my test functions ran too fast or returned infinity, so was just after a quick hack to slow them down. – Sab Jan 09 '18 at 10:59
  • @Li357 thank your for your reply too. – Sab Jan 09 '18 at 10:59
  • JavaScript code is so long winded & cumbersome. – Sab Jan 09 '18 at 11:36