Promises hell/chaining promises in Javascript

  • Context: Java 
  • Thread starter Thread starter shivajikobardan
  • Start date Start date
  • Tags Tags
    Javascript
Click For Summary

Discussion Overview

The discussion revolves around understanding the behavior of promises in JavaScript, particularly in the context of converting callback hell into a promise-based structure. Participants explore the implications of asynchronous execution and the order of operations in promise chaining.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant expresses confusion about why their initial promise-based code does not produce the expected order of output, suggesting that the timing of promise resolution is not being understood correctly.
  • Another participant explains that the first code block executes all promises simultaneously, leading to outputs based on the timers rather than the order of function calls.
  • Some participants argue that nesting promises may defeat the purpose of asynchronous programming, questioning the rationale behind forcing sequential execution.
  • A later reply emphasizes the importance of understanding the purpose of promises and how they should be utilized to achieve asynchronous functionality effectively.
  • One participant provides a detailed explanation of how the asynchronous nature of promises works, clarifying that the control flow is determined by the timers rather than the order of promise creation.

Areas of Agreement / Disagreement

Participants generally express differing views on the effectiveness and implications of nesting promises. There is no consensus on whether this approach is beneficial or counterproductive, and the discussion remains unresolved regarding the best practices for using promises in JavaScript.

Contextual Notes

Some participants highlight the cognitive challenges of transitioning from synchronous to asynchronous thinking in JavaScript, indicating that the understanding of promises may depend on the specific context of their use.

shivajikobardan
Messages
637
Reaction score
54
TL;DR
asynchronous javascript
https://www.physicsforums.com/threa...-as-well-as-async-await.1048282/#post-6833326
My goal is to convert the callback hell in question to using promises.

The correct flow of program is:
Order created
Order received
Preparing food
Order ready
order delivered

The below code is wrong. If you put 9000 instead of 1000, the flow isn't correct.
JavaScript:
function createorder(timer = 0) {
  return new Promise(function (resolve) {
    setTimeout(resolve, timer);
  });
}

createorder(1000).then(() => {
      console.log('Order Created');
});

createorder(2000).then(() => {
      console.log('Order Received');
});

createorder(3000).then(() => {
  console.log('Preparing Food');
});

createorder(4000).then(() => {
  console.log('Order Ready');
});

createorder(5000).then(() => {
  console.log('Order Delivered');
});

But I fail to understand why it's wrong. Let's do a dry run of it:

Assume 9000 instead of 1000.

Wait 9s till the promise is resolved then "order created" gets printed.
Wait 2s till the promise is resolved then "order received" gets printed.
Wait 3s till the promise is resolved then "preparing food" gets printed.
Wait 4s till the promise is resolved then "order ready" gets printed.
Wait 5s till the promise is resolved then "order ready" gets printed.
I did it using promises hell and it's correct
JavaScript:
function createOrder(timer)
{
  return new Promise(function(resolve,reject){
    setTimeout(resolve,timer);
  })
}
createOrder(9000).then(function(){
  console.log("Order created");
  createOrder(1000).then(function(){
    console.log("order received");
    createOrder(1000).then(function(){
      console.log("preparing food");
      createOrder(1000).then(function(){
        console.log("order ready");
        createOrder(1000).then(function(){
          console.log("order delivered");
        })
      })
    })
  })
})

Dry run:

1) Wait 9s till promise is resolved, then print "order created".
then
2) Wait 1s till promise is resolved, then print "order received".
then
3) Wait 1s till promise is resolved, then print "preparing food".
then
4) Wait 1s till promise is resolved, then print "order ready".
then
5) Wait 1s till promise is resolved, then print "order delivered".
I must say I kinda get why this works (The "then".."then".."then".."then" makes it clear). But I don't understand why the first code block doesn't work.
I'm really finding it tough asynchronous javascript. I'm really out of ideas, and only a good analogy to learn can save me now.
 
Technology news on Phys.org
PS the code copying feature doesn't seem to work in PF.
1671543008502.png
 
shivajikobardan said:
Assume 9000 instead of 1000.

Wait 9s till the promise is resolved then "order created" gets printed.
Wait 2s till the promise is resolved then "order received" gets printed.
Wait 3s till the promise is resolved then "preparing food" gets printed.
Wait 4s till the promise is resolved then "order ready" gets printed.
Wait 5s till the promise is resolved then "order ready" gets printed.
My thoughts, with no convenient way to verify them, is that these calls to createOrder() aren't happening synchronously -- while the timer is running for the "order created" call, the other calls are executing. If my logic is correct, you would see "order received", "preparing food", and then "order ready" either before or after "order created".
 
It's been, like, five years, which is five millennia in JavaScriptland but...

Doesn't nesting the promises defeat the whole purpose of asynch? The rationale of asynch the assumption that you can't count on any particular data arriving in time for other activities, If you force that, what's the point?
 
DaveC426913 said:
It's been, like, five years, which is five millennia in JavaScriptland but...

Doesn't nesting the promises defeat the whole purpose of asynch? The rationale of asynch the assumption that you can't count on any particular data arriving in time for other activities, If you force that, what's the point?
Interesting instructor also used similar wordings like yours. Could you explain a bit more?
 
shivajikobardan said:
Interesting instructor also used similar wordings like yours. Could you explain a bit more?
I remember having the same cognitive roadblock when learning: "Promises are The New Thing. Now, how do I cram them into my old, synchronous way of thinking?"

I think the question you need to ask yourself is: what are you trying to accomplish by using promises? Knowing that their very purpose is asynchrony, how are you using that to help your functionality?

At the risk of being glib, is it possible that you've been given a hammer and are concluding your app must be made of nails?I think we need to understand the parameters of the assignment before we can decide how to design it. For starters, is this a learning assignment or is it a real-world application?
 
Last edited:
shivajikobardan said:
I don't understand why the first code block doesn't work.
It does work since it does exactly what you ask for.

You create a promise and ask to wait for 9s and then write "order created";

Then the code jumps to the next line - while the first promise is working asynchronously - where you ask to wait for 2s and then write "order received";

Then the code jumps to the next line - while the first and second promises are working asynchronously - where you ask to wait for 3s and then write "preparing food";

Then the code jumps to the next line - while the first, second, and third promises are working asynchronously - where you ask to wait for 4s and then write "order ready";

Then the code jumps to the next line - while the first, second, third, and fourth promises are working asynchronously - where you ask to wait for 5s and then write "order delivered";

All of this is done really fast (in the order of milliseconds) and all your promises are working together. Of course, they will resolve according to the time you set, so the text with the shortest time will appear first and the one with the longest time will appear last.

In the second example, you ask to do the next step only after the previous promise is resolved (activating the "then" function). So for the code to find out about the next promise to execute, it has to wait for the signal of the "parent" promise.
 
  • Like
Likes   Reactions: pbuk
shivajikobardan said:
TL;DR Summary: asynchronous javascript

The below code is wrong.
Yes. That's because each call to createOrder returns immediately. That's what an async function does; it returns immediately, as soon as you call it, and the thing it returns is a promise, i.e., an object that represents an action that hasn't been completed yet. Caling .then on the return value of createOrder then also returns immediately, since .then is another async function that returns a promise.

So your "dry run" for this case is wrong. Here's what actually happens:

Set a timer that will go off in 9 seconds, and immediately return a promise that represents it; then call .then on this promise, which sets up a print statement to happen when the timer goes off, and immediately return an updated promise that represents that.

Do the same with 4 more timers and 4 more corresponding print statements.

All of this will return, and control flow will be at the bottom of your code block, before the first timer goes off. So what is actually controlling the order in which the print statements execute is the timing on the timers, not the order in which you make the function calls. The timers all start at basically the same time (since the time it takes to execute all of your code and return promises is negligible, much less than a second), so their timeouts control the order in which the timers go off and the print statements execute. And indeed that's what you're seeing.

In your second example, you are instead using repeated calls to .then to control the order in which the print statements execute, as well as using the timers to control the delays between them. That's why your "dry run" is correct for this case.
 
  • Like
Likes   Reactions: pbuk
DaveC426913 said:
Doesn't nesting the promises defeat the whole purpose of asynch?
No. What it does is allow you to control the order in which certain things happen, while still taking advantage of the fact that, while those things are happening, your code can be doing something else. The real "async" that allows all that is happening deep inside the runtime engine, not anywhere in your code. That's why async code is often hard to reason about: because you can't see the actual control flow that is happening down in the runtime engine, where it is keeping track of all the async tasks that haven't completed and what each one is waiting on.
 
  • Informative
  • Like
Likes   Reactions: pbuk, berkeman and DaveC426913

Similar threads

  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
42
Views
8K
  • · Replies 10 ·
Replies
10
Views
4K
Replies
2
Views
3K