

Let's start with the history of the async/await keywords. They were introduced to EcmaScript in version 8 (year 2017). According to caniuse.com, all major browsers have these keywords implemented. If it turned out that an earlier version of the browser does not support it, TypeScript comes to the rescue, which makes identical keywords available already since version 1.7 released in 2015. It is worth noting here that async/await was added to the C# language even earlier and eventually found its way to TypeScript. And this is because one of the designers of this language is Anders Hejlsberg, the creator of the C# language.
This brings us to the heart of the matter. Thanks to await, we can write asynchronous code as if the execution looked synchronous. Already the introduction of promises reduced callback hell, i.e. multiple nested callbacks:
callbackHell1(function(result1) {
callbackHell2(function(result2) {
callbackHell3(function(result3) {
//etc....
});
});
});
Below is the same example using promises:
callbackHell1().then(function(result1) {
return callbackHell2();
}).then(function(result2) {
return callbackHell3();
}). then(function(result3) {
//etc...
});
It is already good at this stage. But it could be even better. Let's see how it will look when we use await:
const result1 = await callbackHell1();
const result2 = await callbackHell2();
const result3 = await callbackHell3();
Perfect. Everything is now clear and transparent. Keep in mind that this is all just "syntactic icing" and underneath the code actually executes asynchronously. Most importantly, we can only use the word await in the context of a function that will be marked with the async keyword.
async function asyncHeaven(){
return await callbackHell1();
}
And one more important thing - these keywords only work with promises. So we can put await before a call that returns a Promise, and a function marked by async must also return a Promise.
A few words about Observable
When I came across Angular professionally over a year ago, and right away in version 5, and with it the rxjs library, I thought Observable was the new better Promise. Especially since Angular promotes the former in the new http client. It seemed natural to me then to also push the use of Observable in the project I'm involved in. If only to support asynchronous code in a consistent way throughout the project. This has been more or less successful. But I also started to notice some disadvantages. The main difference in how Observable works is that if we don't call the subscribe method on it, then the asynchronous method will not execute. An example is http.get:
Import { HttpClient } from '@angular/common/http';
@Injectable()
export class TestService {
constructor(private http: HttpClient) {}
public getConfig(): Observable < any > {
return this.http.get('someurl');
}
}
If we do not subscribe to the result of the method in the above example, then no GET request will go to the server. This can sometimes be an advantage, but if you have been using promises so far, you may be surprised because we are not obliged to call then.
The second issue is that these objects are not part of the language, and are therefore not explicitly supported by async/await. To do so, we must first convert to a promise using the toPromise method.
This is not all particularly onerous, but it does show that there is no point in using "observables" by force. There are of course situations where promises are not applicable, and rxjs library objects are then irreplaceable.