Reputation: 2351
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
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
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.
Asynchronous vs synchronous execution, what does it really mean?
What is the difference between synchronous and asynchronous programming (in node.js)
Upvotes: 0