23

I had a asynchronous function in Javascript and I added setTimeout to it. The code looks like that:

        let timer;
        clearTimeout(timer);
        timer =setTimeout(() => {
        (async() => {
            await this._doSomething();
        })();
        }, 2000);

The purpose of setTimeout is to add 2 seconds before function will be run. It is to be sure that user stopped typing.

Should I remove async/await from this function now, since setTimeout is asynchronous anyway?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Marta
  • 2,857
  • 13
  • 46
  • 67
  • _"The code looks like that"_ Unlikely, and that's why you shouldn't remove `async` and `await`. It makes no sense in this example, but that doesn't mean it's pointless in (the) real code. – a better oliver Aug 18 '16 at 06:58
  • 1
    It's a bit unclear what you are asking here exactly. How is the piece of code **supposed** to work and how might removing `async` and `await` **change** that? Without a clear question that has an actual *answer* to it, you are just getting very broad and opinionated advice. – noppa Aug 18 '16 at 21:00
  • I have edited question to make it more clear what I am trying to achive. – Marta Aug 19 '16 at 13:04

2 Answers2

53

setTimeout adds a delay before a function call, whereas async/await is syntactic sugar ontop of promises, a way to chain code to run after a call completes, so they're different.

setTimeout has terrible error-handling characteristics, so I recommend the following in all code:

let wait = ms => new Promise(resolve => setTimeout(resolve, ms));

and then never call setTimeout directly again.

Your code now becomes:

let foo = async () => {
  await wait(2000);
  await this._doSomething();
}

except foo waits for doSomething to finish. This is usually desirable, but without context it's hard to know what you want. If you meant to run doSomething in parallel with other code, I recommend:

async () => { await Promise.all([foo(), this._otherCode()]); };

to join and capture errors in the same place.

If you truly meant to fire and forget _doSomething and not wait for it, you can lose the await, but you should try/catch errors:

async () => {
  let spinoff = async () => { try { await foo(); } catch (e) { console.log(e); } };
  spinoff(); // no await!
}

But I don't recommend that pattern, as it's subtle and can be easy to miss.

jib
  • 40,579
  • 17
  • 100
  • 158
-6
/* contrived example alert */
var foo = 'poo';
function setFoo(callback) (
    setTimeout(function(){
        foo = 'bar';
        callback();
    }, 100);
);
setFoo(function() {
    alert(foo);
});
satwick
  • 135
  • 9
  • 1
    I see downvotes but no comments so to clarify the downvotes... How does this answer the question at all? And also you aren't even using an `async` function which is what this question is asking about. – aug Nov 06 '17 at 19:48
  • 1
    Yeah, and you apparently ripped that snippet from this more useful answer on a similar topic... https://stackoverflow.com/a/19626821/1580234 – King Holly Dec 03 '20 at 06:41