For more tips like this, sign up to the weekly newsletter!

Scope async/await variables

In Promise chains, the then functions properly scope the variables declared inside them. They are accessible inside the functions, but not outside.

For example, let's look into a simple chain:

Promise.resolve(10)
  .then((num) => {
    var plusone = num + 1;

    return plusone;
  })
  .then((res) => {
    console.log(res); // 11
  });

The plusone variable does not leak, it is only accessible inside the first then function.

Contrast that with a straightforward rewrite to async/await:

var num = await Promise.resolve(10);
var plusone = num + 1;
console.log(plusone); // 11

// plusone is still accessible

The variable pollutes the scope and breaks the nice encapsulation property of the traditional approach.

Use async IIFE

To scope the variables, use an async IIFE and await for it:

await (async () => {
  var num = await Promise.resolve(10);
  var plusone = num + 1;
  console.log(plusone); // 11
})();

// plusone is out of scope

This is the same approach that scopes vars in a non-async context.

Use block-scoped variables

Alternatively, instead of using an IIFE, block-scoped variables (let and const) and a block also does the trick.

{
  const num = await Promise.resolve(10);
  const plusone = num + 1;
  console.log(plusone); // 11
}

// plusone is out of scope
Try it
Learn more: