3

What’s the use of async and await and why are there so many of them in smart contact tests?

3
  • They are required for asynchronous operations, and using async/await is the way of achieving that in javascript.
    – Ismael
    Commented Sep 18, 2022 at 1:31
  • How do you when an operation should be performed synchronously or asynchronously in smart contract tests? Commented Sep 18, 2022 at 4:11
  • It depends on the language, for javascript regular code is synchronous and asynchronous code should be in an async function.
    – Ismael
    Commented Sep 18, 2022 at 17:59

1 Answer 1

3

Not only on smart contract tests, but in Javascript and Nodejs, in general, is common to find many async/await function calls.

The Javascript is single-threaded. So, how do you get this sense of asynchronicity with just a single thread? Easy, Javascript delegates asynchronous work to the runtime, and when it's done, it receives the response.

Javascript has a single-threaded Event Loop that goes checking the call stack and processing items. If the call stack is empty, it checks the callback queue, gets a response, and starts processing it, putting more items in the stack as the code is executing and keeps processing those, in a loop.

If there is any function execution that would block the only thread, that function execution could be sent to the runtime to handle, like the WebAPIs in the browser. Js is single-threaded, but the browser is not. So the browser can make work in the background and put the results in the callback queue. When the event loop is done processing whatever was in the stack, then it checks to see if it has a response in the callback queue, if so, it processes it. The same applies to Nodejs (with a few extra steps, but with the same principle).

enter image description here

You can play around with it here: https://www.jsv9000.app/

So, if you don't use await to call a function that is async or returns a promise, then it will be sent to the runtime to process asynchronous, it will not wait for the response and it will continue executing the code below that line. This means, that if you were expecting to use a value returned by an async or promise function, you will only get the promise and not the actual response. That's why you use await to wait for the response, running the function as if it was synchronous and not asynchronous.

async/await are just sugar code for promises. If you declare an async function like this:

async function getNumberAsync() {
    return 5;
}

By declaring the getNumberAsync function as async, it will now automatically return a promise that will resolve to a number 5 in this example.

So, you can invoke it in two ways:

const result = await getNumberAsync();
console.log(result);
console.log("More stuff");

Or:

getNumberAsync().then(result => {
   console.log(result);
});
console.log("More stuff");

They are essentially the same. But when doing getNumberAsync().then(...) the code below this line will execute right away and print "More stuff" and then 5 will be printed. The code inside the then will receive the response later on, asynchronously.

With await, the code below that line will not execute until the await line gets the response, so it will print 5 first, and then "More stuff".

If you call the getNumberAsync; function without awaitor.then(...)`, then you will not get the result, but a promise object:

const result = getNumberAsync();
console.log(result);```

Would print:

```js
Promise {<fulfilled>: 5}

Then you can do:

result.then(...);

or:

console.log(await result);

So, you need to be careful when to use which.

Anyways, many of the libraries that we use for smart contract tests (and most other regular libraries) use async/await/promise for functions that will do IO operations like making an http call, etc. This way you don't get your event loop stuck waiting for that response if you don't want it and can continue processing other stuff. So, you have the option to 'stop' the execution at a certain point and wait for the response, or use a promise .then callback function to get notified when the response is ready.

Promises came to help with the "Callback hell". async/await came to help with the "Promise Help".

Check: https://blog.avenuecode.com/callback-hell-promises-and-async/await

4
  • 1
    Since async/await are sugar coating for promises that dictate that an operation needs to be finished first before another one starts executing (make asynchronous code look more like synchronous code) , can’t I just eliminate async/await completely and make promises behave synchronously? Commented Sep 18, 2022 at 4:20
  • 1
    Whoah, pretty thorough answer to a basically JS question. Good work! Commented Sep 18, 2022 at 7:33
  • 1
    Yes, you can, but soon you will face a "promise hell", where you will have so many promise.then(...).then (...).then (...)... that it will make the code hard to read and follow. That's why async/await sugar came to be. Commented Sep 18, 2022 at 14:06
  • How do you know when an operation should be performed synchronously or asynchronously in smart contract tests? Commented Sep 18, 2022 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.