1

problem code is :

var result = 10;
function wait(time,f) {
  setTimeout(function() {
  result = f(result);
  }, time);
}

wait(500, function(x) {return x + 5})
wait(250, function(x) {return x * 2})

I think what the result is 30, but result is 25(solution).

Why the result value is 25?

NoNameProvided
  • 7,079
  • 7
  • 33
  • 59
devsner
  • 89
  • 1
  • 9

2 Answers2

3

You schedule two callbacks:

wait(500, function(x) {return x + 5}) // execute after 500ms
wait(250, function(x) {return x * 2}) // execute after 250ms

The first argument is the time after which the callback will be run. Since the second wait call has the lower first argument, it runs first.

At 250ms or so, since result starts at 10, the x * 2 multiplies result by 2, getting you to 20.

Then, at 500ms or so, the x + 5 runs, getting you to 25.

If you want to be able to do this sort of thing such that the code appears to run more sequentially, use Promises and await instead:

let result = 10;
function wait(time,f) {
  return new Promise(resolve => setTimeout(() => {
    result = f(result);
    resolve();
  }, time));
}

(async () => {
  await wait(250, x => x * 2);
  await wait(250, x => x + 5);
  console.log(result);
})();
CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
  • I find it strange that some parsers will not allow `(function(){})()`, only accepting `(function(){}())`, while they only accept `(()=>{})()`, not `(()=>{}())`. Any idea why, @CertainPerformance? – StackSlave Mar 23 '20 at 02:17
  • 1
    All modern parsers *should* behave identically in such situations - that sort of fundamental syntax is clearly defined in the specification. Still, `(function(){})()` should work just fine (do you have an example link where it appears not to?). `(function(){}())` should always work too. `(()=>{}())` will not, because [*an ArrowFunction cannot be on the LHS of a CallExpression*](https://stackoverflow.com/a/34589765). – CertainPerformance Mar 23 '20 at 02:27
  • I can't remember what Browser, but I did actually have an issue where I had to change `(function(){})()` to `(function(){}())` years ago. I was baffled at the time. I thought it to be a Browser bug, but still had the issue, so I just changed my code, then it worked. I actually prefer the parameters on the outside. Made more sense to me. I'll forget I ever had the issue, now, but I actually did in the past. – StackSlave Mar 23 '20 at 02:55
0

Here is a backward compatible way to achieve what you want, if you want below Edge 15:

const delay = (()=>{
  let n = 0;
  return (time, func)=>{
    n += time; setTimeout(func, n);
    return delay;
  }
})();
let x = 10;
delay(500, ()=>{
  x += 5;
  console.log(x);
})(250, ()=>{
  x *= 2;
  console.log(x);
});
StackSlave
  • 10,198
  • 2
  • 15
  • 30