ThePumpkinMaster
ThePumpkinMaster

Reputation: 2351

Do Promises just make asynchronous code synchronous? Why not just use synchronous code?

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?

Upvotes: 0

Views: 367

Answers (2)

Jeff Bowman
Jeff Bowman

Reputation: 95714

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.)

Upvotes: 3

Alongkorn
Alongkorn

Reputation: 4217

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.

Upvotes: 0

Related Questions