0

I'm just discovering Promises and I'm trying to wrap my head around them. The W3C website has a page dedicated to it, featuring the following code :

let myPromise = new Promise(function(myResolve, myReject) {
  let x = 0;

// The producing code (this may take some time)

  if (x == 0) {
    myResolve("OK");
  } else {
    myReject("Error");
  }
});

myPromise.then(
  function(value) {myDisplayer(value);},
  function(error) {myDisplayer(error);}
);

I tried to make my own try at it, with the following code :

let p = new Promise(function test(resolve, reject){

    // here is supposed to be where the async code takes place, according to the 
    // article.

    let a = 0;

    setTimeout(() => {a = Math.floor(Math.random()*6)}, "1000")

    // ...however the condition triggers before the setTimeout takes place.

    if(a >= 0) {
        resolve(`Success ! a = ${a}`);
    } else {
        reject(`Failure ! a = ${a}`);
    }
});

p.then(function logResult(result){
    console.log(result);
})

So I figured that this should work :

let q = new Promise(function test(resolve, reject){

    let a = 0;

    setTimeout(() => {
        a = Math.floor(Math.random()*6);

        if(a >= 4) {
            resolve(`Success ! a = ${a}`);
        } else {
            reject(`Failure ! a = ${a}`);
        }
    }, "1000")
});

q.then(function logResult(result){
    console.log(result);
})

And it does work, but it's the setTimeout callbacks that handles everything, not the promise itself, and doing it without the promise works just as fine :

let a = 0;

setTimeout(() => {
    a = Math.floor(Math.random() * 6);

    if (a >= 4) {
        console.log(`Success ! a = ${a}`);
    } else {
        console.log(`Failure ! a = ${a}`);
    }
}, "1000")

So there's definitely something I don't understand about how Promises are supposed to handle async code or why they're useful altogether. I wish someone would explain it to me.

Nono Nunu
  • 3
  • 3
  • `setTimeout` isn't aware of promises. So you have to convert `setTimeout` into a promise. You can do it like your way. Or if you are on nodejs, you could use https://nodejs.org/api/timers.html#timerspromisessettimeoutdelay-value-options – derpirscher Jan 22 '23 at 10:28
  • 4
    Generally, W3schols has nothing to do with W3C. They just chose this name because of the similarity. ... And also I would not recommend it as a learning platform, because the informations you get there are often outdated and/or wrong – derpirscher Jan 22 '23 at 10:29
  • Is your question about why the first snippet fails but the second does it, or is it more about why the second is preferred over the third? – Bergi Jan 22 '23 at 12:24

2 Answers2

-1

The whole point of promises is to allow some other code to be executed while waiting for a promise to resolve or reject.

In your code, however, no action takes time; therefore, you can do the same without promises.

The most common scenario for promises is something like this:

  1. Show the user a progress dialog
  2. Request some data from the backend
  3. Once data is retrieved, process it
  4. After data is processed, show it to a user

There will be a delay between steps 2 and 3 because an HTTP request will take some time naturally. Also, step 3 may take some time to process, and we don't want to block our code execution while waiting for it to complete. In this case, we wrap step 2 in a promise and use then to execute steps 3 and 4.

Please let me know if this helps.

RAllen
  • 1,235
  • 1
  • 7
  • 10
  • 2
    This might explain Promises ([which has already been covered](https://stackoverflow.com/help/duplicates) many many times on Stack Overflow), but doesn't really explain OP's core problem: Why the Promise doesn't wait for the `setTimeout()` to complete before resolving/continuing. – Ivar Jan 22 '23 at 10:57
  • @Ivar, thanks for your feedback! I agree with you that my answer doesn't refer to the OPs code. However, OPs request was "or why they're useful altogether. I wish someone would explain it to me.". My answer aims to explain why and when promises are useful. It is hard to explain the usefulness of promises in `setTimeout` scenario that doesn't require promises at all – RAllen Jan 22 '23 at 11:09
  • 1
    @Ivar It doesn't even really explain promises though, since it doesn't answer the question why they are more useful than doing the same with plain callbacks (which is always possible). – Bergi Jan 22 '23 at 12:10
  • @Bergi, you are more than welcome to share a better answer if you have it. The truth is that promises are not really necessary, and they are not bringing anything unique. In some scenarios, they allow us to organize code a bit better and make it more readable, but that's pretty much it. Also, they are just old good callbacks redirected to `then` or `catch` or just blocked by `await` that makes the whole thing synchronous again – RAllen Jan 22 '23 at 14:33
  • 2
    @RAllen [I already did](https://stackoverflow.com/a/22562045/1048572), on the duplicate target :-) – Bergi Jan 22 '23 at 15:38
  • @RAllen Nothing is *really necessary*. But saying that promises are just for readability and code organization, you probably should read some introductions to promises again ... And no, neither does `await` *block* anything, nor does it make asynchronous code *synchronous again* ... – derpirscher Jan 22 '23 at 17:43
  • @derpirscher, thank you for your feedback. Let's look at the documentation together https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await section Description `Using await pauses the execution of its surrounding async function until the promise is settled`. – RAllen Jan 22 '23 at 23:30
  • @RAllen In JS "blocking" has a very well defined meaning, ie blocking the *Main Event Loop*. Read for instance https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/. That's not the case with `async/await` (or the equivalent `.then().catch()`). You should have read the page you cited until the end "*Because await is only valid inside async functions and modules, which themselves **are asynchronous** and return promises, the await expression **never blocks** the main thread and only defers execution of code that actually depends on the result*" "pausing" !== "blocking" – derpirscher Jan 23 '23 at 10:02
  • @derpirscher you are talking in quite a rude tone in every message. There is no need for this in technical discussions. We are here not to insult but to help. Blocking and pausing are the same thing because they both mean stopping execution. It literally means that the next instruction after `await` won't be executed until a promise is fulfilled. Of course, `await` blocks the execution of the function where it is used. The word "blocking" is not a special word that is used exclusively in the context of blocking/non-blocking IO operations and that's why it is used in the `await` desc. – RAllen Jan 23 '23 at 11:00
  • @RAllen I'm not sure what in my posts is rude. But if you read the link I provided you, you can see quite on the top, what the vast majority of the JS-community means when they talk about "blocking". If you don't use it this way, it's your own decision, but you must not wonder when you everybody else misunderstands you. There is a reason, why the docs of `await` say it "pauses" the execution of code instead of it "blocks" it ... And the only way "blocking" is used in the link you gave, is saying "*it never blocks*" (ie in the passage I cited) – derpirscher Jan 23 '23 at 11:09
  • @RAllen And I don't want to play the "authority card" (especially not for myself), I don't know how long and intense you are working with JS. Your rep on SO is currently 71, Bergi on the other hand has a rep of well over 600.000 more or less exclusively from posts about JS, so I actually think, he knows what he is talking about ... – derpirscher Jan 23 '23 at 11:13
-1

Promises are used to handle operations which take longer than others. For example fetching something from a server. Since JavaScript is single-threaded, promises and callbacks are the answer for problems with long executing operations. If you would fetch something from a server synchronously (without a promise or callback), you wouldn't be capable to interact with your app in any other way (Click handlers wouldn't work.). It would block the main thread for the time when it fetches the data. Promises and callbacks are executing when there is nothing left to execute. Using promise to wrap callback function might be used to utilize async/await and .then() with it. It's in addition to prevent what's called - callback hell (a lot of callbacks nested in each other).