My code looks like this:
public getUrl(url) {
//returns URL
... }
public getResponseFromURL(): container {
let myStatus = 4;
const abc = http.get(url, (respon) =>
const { statusCode } = respon;
myStatus = statusCode;
console.log('Inside callback' +myStatus);
.on('error', (err) => {
console.log('Things have gone wrong' + err);
});
console.log('ITS COMPLICATED' +myStatus);
return new Container(status, body, header);
}
}
The problem I am facing is because of the asynchronous nature of JS and the console.log('ITS COMPLICATED') gets executed before the one in the callback function. I am trying to have the first one executed before the last console.log!
I am using Async/Await like below:
public timeoutPromise(time: any) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Date.now());
}, time);
});
}
public doSomethingAsync() {
return this.timeoutPromise(1000);
}
As a result changed my getResponseFromURL() to:
public async getResponseFromURL(): Promise<container> {
this.myStatus = 7;
console.log(0);
await this.doSomethingAsync();
console.log(1);
const abc = http.get(url, (respon) => {
const { statusCode } = respon;
this.myStatus = statusCode;
console.log('Inside Callback ' + statusCode);
}).on('error', (err) => {
console.log('Things have gone wrong ' + err);
});
await this.doSomethingAsync();
console.log(2);
await this.doSomethingAsync();
console.log('Is it simple lalala ' + this.myStatus);
await this.doSomethingAsync();
}
}
The problem with doing this was if my container class (return type of getResponseFromURL()) is a container for status and body when I am testing this async function, before expect.getResponseFromURL().getStatus().toBe(200)
would work.
Test looks like below:
test('Async function', async () => {
expect.assertions(1);
const data = await ContainerGlobals.getResponseFromURL().getStatus();
expect(data).toBe(207);
});
Now I am getting error from .getStatus()
and I am not sure how to bypass this error?
"does not exist on Promise"
In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a . then callback.
Rationale. Marking a function as async without using await or returning a value inside it can lead to an unintended promise return and a larger transpiled output. Often the function can be synchronous and the async keyword is there by mistake.
The await keyword before a promise makes JavaScript wait until that promise settles, and then: If it's an error, an exception is generated — same as if throw error were called at that very place. Otherwise, it returns the result.
Async/Await makes it easier to write promises. The keyword 'async' before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.
In the code above await
is called on the result of calling getStatus
on the result of calling ContainerGlobals.getResponseFromURL()
.
ContainerGlobals.getResponseFromURL()
returns a Promise
and immediately calling getStatus()
on the Promise
gives an error since getStatus
"does not exist on Promise
".
await
needs to be called on the Promise
returned by ContainerGlobals.getResponseFromURL()
, and getStatus
should be called on the result returned by await
.
The quickest way to fix this is to throw parenthesis around the await
:
test('Async function', async () => {
expect.assertions(1);
const data = (await ContainerGlobals.getResponseFromURL()).getStatus();
expect(data).toBe(207); // SUCCESS
});
...but you might want to split the await
line into two lines for readability:
test('Async function', async () => {
expect.assertions(1);
const result = await ContainerGlobals.getResponseFromURL(); // let the Promise resolve
const data = result.getStatus(); // call getStatus on the result
expect(data).toBe(207); // SUCCESS
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With