I am stupidly confused on JS Promises.

fuzzybabybunny

Moderator<br>Digital & Video Cameras
Moderator
Jan 2, 2006
10,455
35
91
I've got three lines of code that must run sequentially:

Code:
1. buildShoppingCartObject(OrderFormContents); // returns ShoppingCartObject

2. getTotalPriceOfSelectedItems(ShoppingCartObject); // returns an updated ShoppingCartObject

3. syncShoppingCartObjectToCollection(ShoppingCartObject);

1. I grab all the form inputs using jQuery (OrderFormContents) and put the results into an object (ShoppingCartObject).

2. I then take the ShoppingCartObject and use that to calculate the total price of all items. After the total price is calculated, I add the total price into the ShoppingCartObject (so the function takes ShoppingCartObject as an arguments and updates ShoppingCartObject with the total price).

3. After the ShoppingCartObject is complete, I sync it to a MongoDB collection.

I tried reading on Promises but I'm afraid I can't quite figure out how to implement them. All I want is to have this code run sequentially. Could anyone demonstrate?

I've using MeteorJS, so it's built on top of Node, if that changes anything.
 

purbeast0

No Lifer
Sep 13, 2001
53,639
6,522
126
unless you are making http requests, all of that is going to be ran sequentially. based on your explanation of what each step does, it doesn't sound like there are any http requests being made and that should run syncronously.

or am i missing something?

the power of promises (at least in my experience) is when you are making different requests to get different data, and you have to wait until you get the data back before you continue on.

EDIT:

in general though, promises work like this. i use angular so i'm going to use angular's $q object as an example. just google $q and you will see how promises are with it.

Code:
var a = function() {
  var deferred = $q.deferred;

  $http.request().success(function(data) {
    deferred.resolve(data);
  }).failure(function() {
    deferred.reject();
  });

  return deferred.promise;
}

var b = function() {
  var deferred = $q.deferred;

  $http.request().success(function(data) {
    deferred.resolve(data);
  }).failure(function() {
    deferred.reject();
  });

  return deferred.promise;
}

a().then(function(aData) {
  b().then(function(bData) {
    // do something  
  }
}

that is the gist of it. that will execute the request in a, then do the request in b, and then you can do whatever you have to do afterwards. the $http.request() stuff is also just pseudocode.
 
Last edited:

fuzzybabybunny

Moderator<br>Digital & Video Cameras
Moderator
Jan 2, 2006
10,455
35
91
Gah, now I'm really confused. I thought that all JS code runs asynchronously, regardless of if it's an http request or not.

Code:
stupidlyBigAndSlowFunction();
reallyFastFunction();

If this code is run, doesn't reallyFastFunction output whatever it outputs before stupidlyBigAndSlowFunction? If reallyFastFunction depended on stupidlyBigAndSlowFunction to finish first, wouldn't this cause the JS program to blow up?
 

purbeast0

No Lifer
Sep 13, 2001
53,639
6,522
126
Gah, now I'm really confused. I thought that all JS code runs asynchronously, regardless of if it's an http request or not.

Code:
stupidlyBigAndSlowFunction();
reallyFastFunction();

If this code is run, doesn't reallyFastFunction output whatever it outputs before stupidlyBigAndSlowFunction? If reallyFastFunction depended on stupidlyBigAndSlowFunction to finish first, wouldn't this cause the JS program to blow up?

it totally depends what you are doing in those functions.

if the stupidlybigandslowfunction is just doing a for loop with 10000 iterations, outputting the index it is at in the console, and the reallyfastfunction is just outputting 1 to the console, the stupidblybiandslowfunction will output all of it's values 1 - 10000 before it outputs the 1 in the reallyfst function.

now if the first function was doing a bunch of dom manipulation, or making http requests, i don't think there is any guarantee that the dom would be updated by the time the 2nd function was hit, because that might kick off other async stuff to change the dom, or the http requests will kick off and the function will continue.
 

fuzzybabybunny

Moderator<br>Digital & Video Cameras
Moderator
Jan 2, 2006
10,455
35
91
it totally depends what you are doing in those functions.

if the stupidlybigandslowfunction is just doing a for loop with 10000 iterations, outputting the index it is at in the console, and the reallyfastfunction is just outputting 1 to the console, the stupidblybiandslowfunction will output all of it's values 1 - 10000 before it outputs the 1 in the reallyfst function.

now if the first function was doing a bunch of dom manipulation, or making http requests, i don't think there is any guarantee that the dom would be updated by the time the 2nd function was hit, because that might kick off other async stuff to change the dom, or the http requests will kick off and the function will continue.

Hmmm... simply manipulating the DOM via jQuery isn't utilizing http requests... is it?

When I think of http requests I think of requests from the client that are getting things from the main server or another server (like a 3rd party API). So if the front end wants to grab data from the server's database, that's an HTTP request, and that would run asynchronously in Javascript, right?

So any function that contains any request to CRUD data from a remote server is going to be run asynchronously?
 

purbeast0

No Lifer
Sep 13, 2001
53,639
6,522
126
Hmmm... simply manipulating the DOM via jQuery isn't utilizing http requests... is it?

When I think of http requests I think of requests from the client that are getting things from the main server or another server (like a 3rd party API). So if the front end wants to grab data from the server's database, that's an HTTP request, and that would run asynchronously in Javascript, right?

So any function that contains any request to CRUD data from a remote server is going to be run asynchronously?

yeah thats correct. an http request means the client is requesting something from the server and expecting a response back. so promises will "wait" for that response back before it continues into the then() after the promise has been resolved.

the thing about dom manipulation is you don't know exactly what it will be rendered to the screen either, so it might not happen as quickly as you think it will. but then again, i only do dom manipulation the way it's supposed to be done in angular so i don't run into issues with that.
 

GregGreen

Golden Member
Dec 5, 2000
1,687
4
81
In addition to the http/AJAX type requests, you'll also find that requests to your MongoDB instance are asynchronous and any code you run inside a setTimeout is also async-ish. There are also a ton of async things that you could do with the Node standard libraries (reading/writing files for example) although a lot of those methods have synchronous alternatives (fs.open vs fs.openSync).
 

beginner99

Diamond Member
Jun 2, 2009
5,318
1,763
136
So any function that contains any request to CRUD data from a remote server is going to be run asynchronously?

per default yes but for example in jquery an ajax request has the paramter "async" which can be set to false. Then it will be run synchronously.

http://api.jquery.com/jquery.ajax/

async (default: true)
Type: Boolean
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.