Jump to content

 

I know this is wrong because if you set createorder(9000) instead of createorder(1000), it doesn't work properly. But why? The syntax seems fine to me.

 

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');
    
    });

 

My goal is to convert the following code using promises(For the matter of learning).

 

    function createOrder() {
      setTimeout(function() {
        console.log("order created");
          setTimeout(function() {
             console.log("order received");
                setTimeout(function() {
                   console.log("preparing food");
                      setTimeout(function() {
                          console.log("order ready");
                              setTimeout(function() {
                                 console.log("order delivered");
                              }, 6000)
                       }, 4000)
                 }, 5000)
          }, 1000)
       }, 2000)
    }
    
    createOrder();
Expected output:

Order created

Order received

Preparing food

Order ready

Order delivered

 

Link to comment
https://linustechtips.com/topic/1475073-why-is-this-code-wrong-javascript/
Share on other sites

Link to post
Share on other sites

In what way doesn't it work? You said what your expected output is, but not what your actual output is. Seems to work fine for me.

 

With your nested example, your timeouts start consecutively. So you wait for two seconds, then you print "Order created" then you wait for one second before calling the next method and so on.

 

With your promise example, all of your timeouts start at the same time. So after one second the first method runs, then after two seconds the next method runs etc. Each method runs independent from the others. With your callbacks a nested method only runs after the out method has started.

 

Also: Please use code tags. Makes things more readable.

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');
});

function createOrder() {
  setTimeout(function() {
    console.log("order created");

    setTimeout(function() {
      console.log("order received");

        setTimeout(function() {
          console.log("preparing food");

          setTimeout(function() {
            console.log("order ready");

            setTimeout(function() {
              console.log("order delivered");
            }, 6000)
          }, 4000)
        }, 5000)
    }, 1000)
  }, 2000)
}

createOrder();

 

Remember to either quote or @mention others, so they are notified of your reply

Link to post
Share on other sites

Quote

With your promise example, all of your timeouts start at the same time. So after one second the first method runs, then after two seconds the next method runs etc. Each method runs independent from the others. With your callbacks a nested method only runs after the out method has started.

i still can't get why they're running independent of each other. What's then() doing then..

Here is how I view the code.

first call createOrder(1000), after 1sec it will be resolved then print "order created".

then call createOrder(2000), after 2 sec it will be resolved, then print "order received".

Now say I send 9000 instead of 1000 in createorder.

First call createorder(9000), wait 9s resolves, print "order created".

Then go to another block and execute it.


What am I missing here?

Link to post
Share on other sites

18 minutes ago, shivajikobardan said:

i still can't get why they're running independent of each other. What's then() doing then..

"then" defines what you want to happen once the time has elapsed. It isn't blocking for the rest of your code. The whole idea behind using promises is to do things in an asynchronous non-blocking way.

 

Don't think of it as "wait for one second then do X". Think of it as telling someone to do something at a specific time. This does not prevent them from doing something else in the meantime.

 

createOrder(1000).then(…)
createOrder(2000).then(…)

 

This will schedule something to happen after 1 second, then immediately schedule something to happen after two seconds. Whatever you've put inside "then" will happen after the delay you've specified. There's nothing here that would prevent the second "createOrder" to run immediately after the first "createOrder".

 

If you wanted the second createOrder to be called only after the first createOrder, you'd need to put it inside the "then" block.

Remember to either quote or @mention others, so they are notified of your reply

Link to post
Share on other sites

4 hours ago, Eigenvektor said:

"then" defines what you want to happen once the time has elapsed. It isn't blocking for the rest of your code. The whole idea behind using promises is to do things in an asynchronous non-blocking way.

 

Don't think of it as "wait for one second then do X". Think of it as telling someone to do something at a specific time. This does not prevent them from doing something else in the meantime.

 

createOrder(1000).then(…)
createOrder(2000).then(…)

 

This will schedule something to happen after 1 second, then immediately schedule something to happen after two seconds. Whatever you've put inside "then" will happen after the delay you've specified. There's nothing here that would prevent the second "createOrder" to run immediately after the first "createOrder".

 

If you wanted the second createOrder to be called only after the first createOrder, you'd need to put it inside the "then" block.

I see. I'm close to understanding it.

Link to post
Share on other sites

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");
        })
      })
    })
  })
})
promises hell to the rescue. I think I got now why the earlier code didn't work as expected.
Link to post
Share on other sites

28 minutes ago, shivajikobardan said:
promises hell to the rescue. I think I got now why the earlier code didn't work as expected.

Think about it like asking a person to do something in one hour, then asking them to do something else in two hours. They are not blocked for that hour and can do other things in the meantime. Both schedules start right away and things will happen one hour and two hours from now.

 

In your other example (the nested promises), you're only telling the person to do something in one hour. Only when that hour has passed and they're doing that one thing do you tell them to do something else in two hours. So the second schedule only starts once the first schedule has elapsed. Which means looking at it from the original start time, it'll happen in three hours (2 hours after the one hour has already passed)

Remember to either quote or @mention others, so they are notified of your reply

Link to post
Share on other sites

I'm confused again. SORRY.

Dry run of first code is this:

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.

 

What's missing? Everything seems fine here. I Understand why second code works though, it just feels inituitive to understand with nests.

The only way I can understand this is via analogies like you gave...Yours is not entering my head atm...although I thank you for all the efforts.

Link to post
Share on other sites

23 minutes ago, shivajikobardan said:

I'm confused again. SORRY.

Dry run of first code is this:

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.

 

What's missing? Everything seems fine here. I Understand why second code works though, it just feels inituitive to understand with nests.

The only way I can understand this is via analogies like you gave...Yours is not entering my head atm...although I thank you for all the efforts.

Could you try to explain in more detail what you have issues with? It's not really clear what you're confused about to begin with.

 

As I said above, there is no "wait" involved here. Maybe that's your confusion? When you say "print order created in 9 seconds", the code does not wait or sleep until then. It'll schedule the execution, then immediately continue with the next line, where it is asked to schedule something else in 2 seconds.

 

Think about me giving you these instructions:

- In one hour (from now) you will make a post that says "This is my first post"

- In 30 minutes (from now) you will make a post that says "This is my second post"

 

Yes, you have to "wait" until 30 minutes have passed before you make a post, but you're not blocked until then. You can do other stuff in the meantime, you simply have to set up an alarm clock to remind you to do it. And the order of posts will appear out of order to people, because that's what I told you to do. Your first post will happen 30 minutes from now, because you are able to read and understand the second instruction before having completed what the first one is asking you to do.

 

Now take the "nested" case. This alters the instructions slightly:

- In one hour (from now) you will make a post that says "This is my first post"

- Once you've made your post, you will make another post 30 minutes later (i.e. after the first post), that says "This is my second post"

 

In this case your first post will happen one hour from now and the second post will happen after 30 minutes relative to that time, i.e. 1.5 hours from now.

Remember to either quote or @mention others, so they are notified of your reply

Link to post
Share on other sites

One way to look at this, nested vs non-nested (broken) version of it.

 

To give an analogy, imagine you have 5 egg timers at your disposal.

 

Each time you call createOrder you grab an egg timer and set the clock (and leave a note what to do)

 

So lets imagine

createOrder(5).then("Jump")

createOrder(6).then("Honk")

 

What that now translates into is like asking someone the following:

Grab an egg timer and set it to 5 seconds with the reminder to "jump"

Grab an egg timer and set it to 6 seconds with the reminder to "honk"

 

If you were were the boss and told an employee to do the above, they would grab 2 egg timers and just set them right then and there (with the notes to do something)

 

Notice that you set 2 egg timers, but they are working independently of each other (or in programming terms they are asynchronous functions)

 

Now in the nested example, it's like asking the following:

Grab an egg timer and set it to 5 seconds with a reminder to "jump and set an egg timer for 6 seconds with a reminder to honk"

 

It's all part of a singular command, where the reminder includes setting another egg timer.  This is effectively synchronous, where one actions waits for another to complete.

 

 

3735928559 - Beware of the dead beef

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×