Difference between synchronous and asynchronous functions

Tags: , ,



I have just started react-native development and came across async functions. Can someone explain a thing or two about it in layman’s terms. I have tried reading articles on it but they all tend to explain it in a very technical way which is a little confusing. I have used other languages but javaScript is not my cup of tea.

My doubts are:

  1. which one acts more like a normal function, synchronous or asynchronous function?
  2. while reading this article https://blog.expo.io/react-native-meets-async-functions-3e6f81111173 he talks about returning promises and awaiting response. so in this what is a promise and also if we are awaiting response shouldn’t it be a synchronous function?
  3. And ofcourse the differences between synchronous and asynchronous function

Answer

This is a challenging topic when coming from other programming languages. Using your terminology, a ‘normal’ function is akin to a synchronous function.

I’d recommend the MDN docs for await. Read that page and then run the f1 example — I’ve included it below with a couple of enhancements:

  1. I’ve added timestamps to console.log so timing is more obvious
  2. I’ve added console.log statements immediately before and after the call to f1().

The await keyword doesn’t mean wait (or block) when inside an async function. It splits the execution flow, pausing the f1 function (which will be resumed about 2 seconds later) and returning a Promise to the caller that allows the caller of the async function to choose if he wants to await the result of the async function or not. In the code below we print out the result of the call to f1() but we choose not to await the deferred result and we just continue onwards to the next console.log.

Run this code in Node.js:

///////////////////////////////////////////////////////////////////////
// This is just setting up timestamps for console.log
///////////////////////////////////////////////////////////////////////
const oldlog = console.log;

console.log = function () {
  var args = [].slice.call(arguments);
  oldlog.apply(console.log,[getTimestamp()].concat(args));
};

const getTimestamp = () => '[' + (new Date()).toISOString() + ']';

///////////////////////////////////////////////////////////////////////
// Real code starts here
///////////////////////////////////////////////////////////////////////
function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  console.log('enter f1');
  const x = await resolveAfter2Seconds(10);
  console.log('exit f1, x =', x);
  return x;
}

console.log('before f1');
const y = f1();
console.log('after f1, y =', y);

When run, this will result in something like the following:

[2020-03-03T01:48:50.716Z] before f1
[2020-03-03T01:48:50.719Z] enter f1
[2020-03-03T01:48:50.720Z] after f1, y = Promise { <pending> }
[2020-03-03T01:48:52.725Z] exit f1, x = 10

Note specifically that we see the after f1 log before we see the exit f1 log. The execution flow was split and f1() was paused while the caller of f1() continued. The execution of f1() resumed about 2 seconds later.

Now, compare that with what happens if we instead await the result from calling f1(). Note that because we are now using await we must wrap the code in async (an async IIFE, actually) because await can only be used inside an async function.

// console.log('before f1');
// const y = f1();
// console.log('after f1, y =', y);

(async () => {
  console.log('before f1');
  const y = await f1();
  console.log('after f1, y =', y);
})();

Now, the output is as follows:

[2020-03-03T02:19:18.122Z] before f1
[2020-03-03T02:19:18.124Z] enter f1
[2020-03-03T02:19:20.130Z] exit f1, x = 10
[2020-03-03T02:19:20.130Z] after f1, y = 10

Note that now, because the caller chose to await the result of calling f1(), we see the after f1 and exit f1 logs reversed (and in the ‘normal’ order, using your terminology). And now the result of f1() is 10, rather than a pending Promise.

So, this is mildly tricky stuff and I encourage more reading and experimentation to get to grips with it. It looks complex but it is actually simpler to write asynchronous JavaScript code now than it was prior to the introduction of async/await into the language.



Source: stackoverflow