2

While learning about async in javascript I came across this best practice for a sleep() function in javascript.

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

What is the JavaScript version of sleep()?

In the w3school documentation for setTimeout, it says the first parameter must be a function that will be called when the timer resolves. So if resolve is a function, is it just skipped because its never implemented?

What exactly is going on here? I'm a little dyslexic so sorry if this is obvious.

Sujio
  • 55
  • 5

2 Answers2

3

They are both the same.

The first example you provided, if written in full, would look like this:

function sleep(ms) { return new Promise((resolve) => { return setTimeout(resolve, ms) }); }

(note: this is your first function, not your second - although they are essentially the same I'd like to emphasize that this is a rewrite of your first function)

That is, you are passing the anonymous function:

(resolve) => {
  return setTimeout(resolve, ms)
}

to the Promise. However, the syntax of arrow functions allow some shortcuts.

The first shortcut is that if the function has just one statement you can omit the {}. That is to say the function above can be written in shorthand as:

(resolve) => setTimeout(resolve,ms);

So

(resolve) => {
  return setTimeout(resolve, ms)
}

and

(resolve) => setTimeout(resolve,ms);

is exactly the same function but the second version is written in shorthand.

Another shortcut is that if a function accepts only one argument you can remove the () around the arguments. So the function above can be rewritten as:

resolve => setTimeout(resolve,ms);

Note this is exactly the same as:

(resolve) => {
  return setTimeout(resolve, ms)
}

only written in shorthand.


Additional answer.

You asked

So if resolve is a function, is it just skipped because its never implemented?

You are mistaken. It is not never implemented. It is implemented by the person who wrote the Promise class.

Here's what the Promise class does:

If you call me as a constructor then you need to pass a function with two arguments to me. I will call your function later with two arguments, both functions, that you may call. If you call the first function then I will assume you are OK. If you call the second function then I will assume there was an error.

That's all there is to it. The two arguments (usually called resolve and reject but you can name them anything) are defined by the Promise class and will be passed to your function when the Promise class calls your function.

Here's an example implementation of my own Promise class to demonstrate what's going on:

// Warning. For illustration purposes only. This class does not
// fully implement the Promise design pattern as specified by ECMA262:

class Promise {
    constructor (yourfunction) {
        this.result = undefined;
        this.error = undefined;

        function resolve (x) {this.result = x};
        function reject (y) {this.error = y};

        yourfunction(resolve,reject); // calling your function!!
    }

    then (yourcallback) {
        yourcallback(this.result);
    }

    catch (yourcallback) {
        if (this.error) yourcallback(this.error);
    }
}
slebetman
  • 93,070
  • 18
  • 116
  • 145
  • I see. The additional answer is what I was looking for. I must have missed it while reading the documentation. Thank you – Sujio Jan 04 '21 at 08:08
1

The parentheses around the parameter list of an arrow function with a single parameter are optional. The two syntaxes are exactly equivalent:

resolve => …
(resolve) => …

Which one you use is a style preference, and not a matter of best practice.

Arrow function parameter lists with more than one parameter always need parentheses.

const add = (a, b) => a + b;

add(1, 2)
// returns 3

The parentheses don’t denote a function call, just like (ms) isn’t a function call in function sleep(ms).

Ry-
  • 199,309
  • 51
  • 404
  • 420
  • Ah I see, but that still doesn't answer my question, I will edit my question for clarity – Sujio Jan 04 '21 at 07:55
  • @Sujio: `resolve => setTimeout(resolve, ms)` is a function. It’s like `function startSomePromiseWork(resolve) { setTimeout(resolve, ms); }` followed by `return new Promise(startSomePromiseWork);`. – Ry- Jan 04 '21 at 08:00