/babel-preset-better-async-await

Babel preset for babel plugin better async await

Primary LanguageJavaScript

babel-preset-better-async-await

All Contributors

Babel preset for the babel-plugin-better-async-await plugin. babel-plugin-better-async-await.

Install

$ npm install --save-dev babel-preset-better-async-await

or with yarn

$ yarn add babel-preset-better-async-await --dev

⭐ Usage

Via .babelrc (Recommended) without options

.babelrc

{
  "presets": ["better-async-await"]
}

If you are using babel-preset-env or @babel/env or babel-plugin-transform-async-to-generator, then the order of presets matter

{
  "presets": ["better-async-await", "@babel/env"]
}

Via .babelrc (Recommended) with options

.babelrc

{
  "presets": [
    [
      "better-async-await",
      {
        "mode": "strict"
      }
    ]
  ]
}

If you are using babel-preset-env or @babel/env or babel-plugin-transform-async-to-generator, then the order of presets matter

{
  "presets": [
    [
      "better-async-await",
      {
        "mode": "strict"
      }
    ],
    ["@babel/env"]
  ]
}

Via CLI

babel --presets better-async-await script.js

If you are using babel-preset-env or @babel/env or babel-plugin-transform-async-to-generator, then the order of presets matter

babel --presets better-async-await @babel/env script.js

Via Node API

without options:

require("babel-core").transform("code", {
  presets: ["better-async-await"]
});

with option:

require("babel-core").transform("code", {
  presets: [
    [
      "better-async-await",
      {
        mode: "strict"
      }
    ]
  ]
});

If you are using babel-preset-env or @babel/env or babel-plugin-transform-async-to-generator, then the order of presets matter

without options:

require("babel-core").transform("code", {
  presets: ["better-async-await", "@babel/env"]
});

with option:

require("babel-core").transform("code", {
  presets: [
    [
      "better-async-await",
      {
        mode: "strict"
      }
    ],
    ["@babel/env"]
  ]
});

Options

mode

  • strict: In this mode variable names on the left of await statement should match the following rule:-
const [err, resp] = await api.getData(5);
// ...

In Strict Mode

  • Variable name on the left for error should be err
  • Variable name on the left for response should be resp

In non-strict mode

  • Variable names on the left can be anything

Motivation and Idea

This babel plugin is inspired from the idea of this post https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/ written by - Dima Grossman

In async/await functions we often use try/catch blocks to catch errors.

For example:-

async function completeApplicationFlow() {
  // wait for get session status api to check the status
  let response;
  try {
    response = await getSessionStatusApi();
  } catch (err) {
    // if error show a generic error message
    return handleError(err);
  }

  // wait for getting next set of questions api
  try {
    response = await getNextQuestionsApi();
  } catch (err) {
    // if error show a generic error message
    return handleError(err);
  }

  // finally submit application
  try {
    response = await submitApplication();
  } catch (err) {
    // if error show a generic error message
    return handleError(err);
  }
}

Approach inspired from the blog and a different way of doing this could be:-

async function completeApplicationFlow() {
  // wait for get session status api to check the status
  let err, response;
  // wait for get session status api to check the status
  [err, response] = await getSessionStatusApi();
  // if error show a generic error message
  if (err) return handleError(err);
  // call getNextQuestion Api
  [err, response] = await getNextQuestionsApi();
  // if error show a generic error message
  if (err) return handleError(err);
  // finally submit application
  [err, response] = this.submitApplication();
  if (err) return handleError(err);
}

📒 Examples of using it in your code

Before

async function test() {
  let resp;
  try {
    resp = await api.getData(5);
  } catch(err)
    handleError();
  }
}

After

async function test() {
  const [err, resp] = await api.getData(5);
  if (err) handleError();
  // else do something with the response
}

Before

async function test() {
  let resp;
  try {
    resp = await getData;
  } catch(err)
    handleError();
  }
}

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(true);
    }, 1000);
  });
}

After

async function test() {
  const [err, resp] = await getData;
  if (err) handleError();
  // else do something with the response
}

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(true);
    }, 1000);
  });
}

Before

async function test() {
  let resp;
  try {
    resp = await fetch('http://some-rest-endpoint');
  } catch(err)
    handleError();
  }
}

After

async function test() {
  const [err, resp] = await fetch("http://some-rest-endpoint");
  if (err) handleError();
  // else do something with the response
}

📒 Babel Tranformation

In

async function test() {
  const [err, resp] = await fetch("http://some-rest-endpoint");
}

Out

async function test() {
  const [err, resp] = await fetch("http://some-rest-endpoint")
    .then(resp => {
      return [null, resp];
    })
    .catch(error => {
      return [error];
    });
}

Contributors

Thanks goes to these wonderful people (emoji key):


Vivek Nayyar

💬 🐛 💻 🎨 📖 💡 🤔 📦 🔌 👀

This project follows the all-contributors specification. Contributions of any kind welcome!