0

If I'm doing something like:

let request = require('request');

function download(link) {
    return new Promise((resolve, reject) => {
        request.get(link).end((err, res) => {
            resolve(res);
        }); 
    });
}

let link = 'http://google.com';
download(link).then((res) => {
    //do stuff with res
});

Why not just synchronously wait for the request to return? Why even have the promise in the first place?

ThePumpkinMaster
  • 2,181
  • 5
  • 22
  • 31
  • 10
    Because doing it synchronously would block the execution thread from performing any other actions while waiting for the response. – Robby Cornelissen Jun 22 '16 at 02:14
  • Yeah but in the code the promise is wrapping around a request (which is asynchronous with a callback). What is the point of this? – ThePumpkinMaster Jun 22 '16 at 02:40
  • Have a look at the Fetch api which does http requests but returns a promise instead of using the call back style used in node. Promises are just a cleaner alternative to using callbacks. – James Wakefield Jun 22 '16 at 03:15
  • Do you mean "Why not just use callbacks"? –  Jun 22 '16 at 03:20
  • 3
    No, Promises don't make asynchronous code synchronous. [Promises do make asynchronous code easier to express and understand](http://stackoverflow.com/a/22562045/1048572). – Bergi Jun 22 '16 at 06:48
  • So Promises are just an alternative to callbacks? Like anything you can do with callbacks you can do with promises (and vice versa)? They are always used for asynchronous behavior right? Because callbacks are for asynchronous behavior? – ThePumpkinMaster Jun 22 '16 at 13:51
  • @PraneethVT yes anything you can do with callbacks you can do with promises, but *not* the other way around, at least not easily. Promises have more features than callbacks. – Matthias May 01 '19 at 22:07

2 Answers2

3

The main reason is that, if you were to run synchronously, all Javascript would block while your synchronous request is being processed. This may cause the browser to "freeze up" or otherwise cause a bad user experience, and as such is best avoided.

Though there are some exceptions, typical Javascript has single-threaded behavior:

Each message is processed completely before any other message is processed.

Consequently, if you have a synchronous time-consuming action--waiting for an AJAX response, opening a local file, or even just a slow computation--no Javascript will be run until the action is complete. Your page may even appear to freeze, causing the browser or operating system to offer to kill the page or application. As noted on MDN's documentation on synchronous XMLHttpRequests, "synchronous requests on the main thread have been deprecated due to the negative effects to the user experience."

Naturally, synchronous code is easier to understand, even with all the pitfalls noted above:

// BAD: This will block while each request takes place,
// regardless of whether that's 10 milliseconds or 10 seconds.
var number1 = getFirstNumberSynchronouslyFromServer(url1);
var number2 = getSecondNumberSynchronouslyFromServer(url2);
display(number1 * number2);

Up through ES6, the easiest way to handle this was with callback methods:

getFirstNumberAsynchronously(url1, function(number1) {
  getSecondNumberAsynchronously(url2, function(number2) {
    display(number1 * number2);
  });
});

But that gets tricky, particularly when error handling is involved, and particularly when trying to abstract away a value that might be available already or might need another time-consuming request or computation. ES6's Promises go most of the way to solving that:

var number1, number2;
getFirstNumberPromise().then(function(result) {
  number1 = result;
  return getSecondNumberPromise();
}).then(function(result) {
  number2 = result;
  return number1 * number2;
}).then(display).catch(handleError);

And ES7's async/await finish the job to make the asynchronous version as easy to read/understand as the synchronous version:

var number1 = await getFirstNumberPromise();
var number2 = await getSecondNumberPromise();
display(number1 * number2);

(As it happens, all of the above examples request each number sequentially. With Promises.all, it's easy to do so in parallel in the Promise-based example, and much more complicated in the nested callback, synchronous, or pseudo-synchronous examples.)

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
0

The main difference is synchronous code will block next statement, but asynchronous code will block nothing.

asynchronous code allow us to do multiple tasks in the same time, but synchronous code will not.

The 2 threads provide the great description. It is good to read.

Community
  • 1
  • 1
Alongkorn
  • 3,968
  • 1
  • 24
  • 41