An asynchronous function is just a regular function that returns a Promise instead of a Number, String, etc.

function asynchronousFunction() {
  const executorFunction = (resolve) => {
    setTimeout(() => resolve("foo"), 2000);
  };
  return new Promise(executorFunction);
}

function synchronousFunction() {
  return "bar";
}

asynchronousFunction() // foo
  .then(console.log)
  .catch(console.log);
console.log(synchronousFunction()); // bar

// console.log output:
// bar
// foo

These two functions are called in this order foo -> bar but it gets logged in this order bar -> foo. That's because the first function returns a Promise which takes 2 seconds to return a value and the second function returns it's value immediately.

This scenario where you want to call a function but have to wait for a return value is the exact reason Promises exist. Study the Promise syntax and you'll find it's not too complicated. You simply return new Promise(executorFunction) from any regular function and it becomes asynchronous.

Now notice the executorFunction we're passing as an argument to Promise return new Promise(executorFunction). The promise expects this function because it is going to pass it two callbacks "resolve" and "reject" and this is the core of the Promise API these two callbacks allows you to do anything you want within this Promise and then at any time in the future you can call resolve() or reject() and it will execute either .then or .catch that you attach when you call your Promise function.

In this next example we're going to re-create the fetch function by wrapping a XMLHttpRequest in a Promise.

Wrapping some asynchronous functionality that doesn't already use Promises is a useful technique you can re-use in your own codebase.

function fetchClone(url) {
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest();
    req.responseType = "json";
    req.onload = () => resolve(req.response);
    req.onerror = reject;
    req.open("get", url, true);
    req.send();
  });
}

fetchClone("https://api.github.com/users/tylerbuchea/repos")
  .then(console.log)
  .catch(console.log);

Try it out in CodeSandbox

Resources