JavaScript, by design, is not multithreaded. So unlike your operating system, it can't do two things at once.
However, there are times we need to wait for stuff to come back from the server. In this case, JavaScript can ask the browser to do the work and be notified when that work is done
This is asynchronous programming - having something done in the background and getting notified when it's done.
Originally, we did this with callbacks - so we'd say "hey browser, please do this work, and when you're done, here's a function you can call with the results"
The problem with callbacks is that we often have to do a few things in the background (asynchronously), so the code starts to get difficult to understand, with many layers of nested callbacks.
Along came the promise, which meant that our code could flatten out a bit. Callback code like this:
(EDIT: as noted below, the code above has a bug; I'm not going to remove it, because that would invalidate comments below, but do check out fixes for this code, as shown below!)
Which was a little easier to read and write (and error handling was neater, with .catch())
async/await is a nice way that modern JavaScript let's us use promises with even less code and nesting:
Under the hood, helpers like Babel and TypeScript translate the code above into a version a lot like the promises version, using an old, clever JavaScript feature called generator functions. Don't worry about it too much now though (:
Hope this helps. Apologies for any typos - I'm doing this from my phone.
Edit: Sorry I didn't see the example above the flattened one which is the same as one of my versions.
Your promise example has a bug but it's a really good example where async/await shines over promises.
$.get("/api/request1").then(function(result1){return$.get("/api/request2?q="+result1);}).then(function(result2){// result1 isn't in scope here and will crashconsole.log(result1+" - "+result2);});
result1 isn't accessible in the final then. With promises you lose the simplicity of the .then chain if you want both the first return value and to use it as a trigger for a follow-up request.
These are some ways to do it with promises.
// Store result1 in a higher scopeletresult1;$.get("/api/request1").then(function(_result1){result1=_result1;return$.get("/api/request2?q="+result1);}).then(function(result2){console.log(result1+" - "+result2);});// Bring the scope of the result2 then within the result1 then$.get("/api/request1").then(function(result1){return$.get("/api/request2?q="+result1).then(function(result2){console.log(result1+" - "+result2);});});// Add result1 to second request's response value$.get("/api/request1").then(function(result1){return$.get("/api/request2?q="+result1).then(function(result2){return[result1,result2];});}).then(function(results){console.log(results[0]+" - "+results[1]);});// Use request1 as trigger for request2 and combine the requests/resultsconstrequest1=$.get("/api/request1");constrequest2=request1.then(function(result1){return$.get("/api/request2?q="+result1);});Promise.all([request1,request2]).then(function(results){console.log(results[0]+" - "+results[1]);});
With async/await, as Davyd has shown above, you have a single scope. No workarounds are needed.
JavaScript, by design, is not multithreaded. So unlike your operating system, it can't do two things at once.
However, there are times we need to wait for stuff to come back from the server. In this case, JavaScript can ask the browser to do the work and be notified when that work is done
This is asynchronous programming - having something done in the background and getting notified when it's done.
Originally, we did this with callbacks - so we'd say "hey browser, please do this work, and when you're done, here's a function you can call with the results"
The problem with callbacks is that we often have to do a few things in the background (asynchronously), so the code starts to get difficult to understand, with many layers of nested callbacks.
Along came the promise, which meant that our code could flatten out a bit. Callback code like this:
Could be a little simpler:
(EDIT: as noted below, the code above has a bug; I'm not going to remove it, because that would invalidate comments below, but do check out fixes for this code, as shown below!)
Which was a little easier to read and write (and error handling was neater, with
.catch()
)async/await
is a nice way that modern JavaScript let's us use promises with even less code and nesting:And you can use try/catch to handle errors.
Under the hood, helpers like Babel and TypeScript translate the code above into a version a lot like the promises version, using an old, clever JavaScript feature called generator functions. Don't worry about it too much now though (:
Hope this helps. Apologies for any typos - I'm doing this from my phone.
Edit: Sorry I didn't see the example above the flattened one which is the same as one of my versions.
Your promise example has a bug but it's a really good example where async/await shines over promises.
result1
isn't accessible in the finalthen
. With promises you lose the simplicity of the.then
chain if you want both the first return value and to use it as a trigger for a follow-up request.These are some ways to do it with promises.
With async/await, as Davyd has shown above, you have a single scope. No workarounds are needed.
Nice catch. I could hardly see all the text on my phone when I was typing. Was bound to have at least one glaring flaw (:
Now, I'm at a pc, I think I'd probably correct to:
(assuming I can use short notation for objects in this particular js-world)
And I think that illustrates even better why async/await is a win (: