0

I am a novice in javascript and I've been learning about promises, recently I started working in some simple list that is retrieved with a random delay (setTimeout), a classical I think. After trying and doing some research I found I post that helped me a lot, and it works fine, but after reviewing what that post suggest against I had done before I noticed that the difference are two brackets...I've been reading and trying to understand why that brackets make such a difference (both options are functional) but I don't get it.

Could some one explain what's the difference? The brackets I mentioned are in function loadIng(), lines 5 and 12, the open bracket in first line and the closing one in the second.

{
    new Promise(resolve => {
    ...
    })
}

If I run the code with the brackets it runs synchronously, but if I run it without the brackets it runs asynchronously...I really don't get it.

function loadIngs() {
    p = Promise.resolve();
    for (let [k, v] of someArray) {
        p = p.then(() => 
            {new Promise(resolve => { //this
                delay = Math.random() * 2000;
                console.log(`${k}:${v} comes delayed for ${delay}`)
                setTimeout(() => {
                    console.log("executes some function")
                    resolve();
                }, delay);
            })} //this
        );
    }
}
riggedCoinflip
  • 435
  • 4
  • 16
  • 1
    hi, I it recommended to produce the `minimal reproducible example` - meaning - delete all code that is not directly related to your code. This includes all of the HTML and CSS you provided and much of the JS script as well. You make it easier for us to help you by writing a concise example. – riggedCoinflip Jun 19 '21 at 14:15
  • Please show a runnable example where it runs asynchronously. The brackets you refer to appear to be part of a function definition (though it isn't clear which example in your code you're talking about) so the code would run whenever that function is called. – jfriend00 Jun 19 '21 at 14:46
  • 2
    If you're talking about the `new Promise()` in the `loadIngs()` function, then the brackets there are optional. A single statement arrow function body may either be declared with or without brackets. Here's a simple example: `setTimeout(() => console.log("hi"), 100)` or `setTimeout(() => { console.log("hi") }, 100)`. These are the same thing. There is no synchronous/asynchronous difference or any execution difference between these two pieces of code here. – jfriend00 Jun 19 '21 at 14:59
  • @jfriend00 confirm the same thing, i check in debugger gives all the time asynchronous, at same time in documentation writes explicitly ``The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.`` The brackets are optional, if you use they its for more than one line script if not, don't use they. – Alumno Cabreado Jun 19 '21 at 15:06
  • You need to `return` the promise in the `p = p.then(() => …)` chain, otherwise the functions won't chain anything. The syntax with the braces returns `undefined` unless you add a `return` keyword. – Bergi Jun 19 '21 at 16:32
  • Btw your `setIng` function should not be using promises or return a promise at all: everything it does is synchronous. – Bergi Jun 19 '21 at 16:33

1 Answers1

1

The difference here has to do with the automatic return value of an arrow function that does not use brackets around a single statement function body.

If you're talking about the new Promise() in the loadIngs() function, here:

function loadIngs() {
    p = Promise.resolve();
    for (let [k, v] of ings) {
        p = p.then(() => 
            {new Promise(resolve => {
                delay = Math.random() * 2000;
                console.log(`${k} comes delayed for ${delay}`)
                setTimeout(() => {
                    setIng(k, v);
                    resolve();
                }, delay);
            })}
        );
    }
}

then the brackets around that new Promise() there are somewhat optional.

A single statement arrow function body may either be declared with or without brackets. Here's a simple example:

setTimeout(() => console.log("hi"), 100) 

setTimeout(() => { console.log("hi") }, 100)

These are nearly the same thing. Since the function body is a single statement console.log("hi"), the arrow function body may stand alone or may be surrounded with brackets. Either is fine and generates the same execute EXCEPT for the return value. If you use brackets, then you need a return statement if there's a specific return value you want. Without the brackets the value of the single statement automatically becomes your return value of that arrow function.

This return value makes a difference in your promise example. So, for the p.then(() => ...) structure in the loadIngs() function. It can either be:

p.then(() => { return new Promise(...) })

or it can be:

p.then(() => new Promise(...) )

These two execute identically. But, notice that this is NOT exactly the same as shown in your code. I added a return in front of the new Promise(). When you remove the return, then this:

p.then(() => { new Promise(...) })

Has no return value from the arrow function. That means that while you create a new promise, you don't return it from the .then() handler and thus it is not linked into the parent promise chain and you get multiple independent promise chains.

This WILL create an execution difference and is probably responsible for what you say when you say one "runs asynchronously". That isn't exactly how I would describe it, but it does create a difference in the timing of when things run because in one case you have a single linked promise chain and in the other case you have two separate, independent promise chains.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • "*The same is true for the `p.then(() => ...)` structure in the `loadIngs()` function. These execute identically.*" - no, they absolutely don't: you forgot about the missing `return`. One function returns a promise that will be awaited by the `then` chain, the other returns `undefiend`. It's the reason why the two codes are executing differently and lead to different results. – Bergi Jun 19 '21 at 16:29
  • 1
    @Bergi - Already was in the process of correcting that when you posted your comment. – jfriend00 Jun 19 '21 at 16:32
  • @jfriend00 thank you for your help. I can see clearly the difference...I think I hadn't fully understood an arrow function's automatic return value before. – Hugo Rodríguez Jun 20 '21 at 16:27
  • @HugoRodríguez - If this answered your question, then you can indicate that to the community by clicking the checkmark to the left of the answer. That will also earn you some reputation points for following the proper procedure here. – jfriend00 Jun 20 '21 at 16:37