Several recommended practices for writing good asynchronous JavaScript code

Safdar Ali - Jun 26 - - Dev Community

Introduction

Asynchronous programming in JavaScript is crucial for building efficient and responsive web applications. However, improper use of asynchronous constructs can lead to performance issues and hard-to-debug errors. Here are several best practices to help you write better asynchronous JavaScript code.

Avoid Using async in the Promise Constructor

Bad Practice

// ❌
new Promise(async (resolve, reject) => {});


Enter fullscreen mode Exit fullscreen mode

Good Practice

// ✅
new Promise((resolve, reject) => {});

Enter fullscreen mode Exit fullscreen mode

Explanation:

Using async within the Promise constructor can lead to unnecessary wrapping of Promises. Additionally, if an async function inside the Promise constructor throws an exception, the constructed Promise will not reject, making it impossible to catch the error. Instead, use a regular function and handle the asynchronous operations within it.

Avoid await Inside Loops

Bad Practice

// ❌
for (const url of urls) {
  const response = await fetch(url);
}

Enter fullscreen mode Exit fullscreen mode

Good Practice

// ✅
const responses = [];
for (const url of urls) {
  const response = fetch(url);
  responses.push(response);
}
await Promise.all(responses);

Enter fullscreen mode Exit fullscreen mode

Explanation:
Using await inside a loop can prevent JavaScript from fully leveraging its event-driven nature. This approach executes fetch requests sequentially, which can be slow. Instead, initiate all fetch requests concurrently and use Promise.all to wait for their completion, significantly improving execution efficiency.

Do Not Return From the Promise Constructor Function

It is not recommended to return a value from the Promise constructor function, as the value returned will be ignored and can cause confusion in the codebase.

Bad Practice


// ❌
new Promise((resolve, reject) => {
  return someValue;
});

Enter fullscreen mode Exit fullscreen mode

Good Practice

// ✅
new Promise((resolve, reject) => {
  resolve(someValue);
});

Enter fullscreen mode Exit fullscreen mode

Explanation:
Returning a value from the Promise executor function does not have any effect. Instead, use resolve to fulfill the promise with the intended value.

Use try...catch for Error Handling in async Functions

Proper error handling is critical in asynchronous code to ensure that your application can gracefully handle failures.

Good Practice

async function fetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Fetch error:', error);
    // Handle the error appropriately
  }
}

Enter fullscreen mode Exit fullscreen mode

Explanation:
Using try...catch blocks within async functions allows you to handle errors gracefully, ensuring that unexpected issues do not crash your application.

Avoid Creating Unnecessary Promises

Creating unnecessary promises can add complexity and reduce the readability of your code.

Bad Practice

// ❌
async function example() {
  return new Promise(async (resolve) => {
    const result = await someAsyncFunction();
    resolve(result);
  });
}

Enter fullscreen mode Exit fullscreen mode

Good Practice

// ✅
async function example() {
  return await someAsyncFunction();
}

Enter fullscreen mode Exit fullscreen mode

Explanation:
If you are already working within an async function, there is no need to wrap another async function in a Promise. The async keyword automatically returns a promise.

Conclusion

By adhering to these best practices, you can write more efficient, readable, and maintainable asynchronous JavaScript code. Avoid using async within Promise constructors, refrain from using await inside loops, ensure proper error handling, and prevent the creation of unnecessary promises. These guidelines will help you leverage the full potential of JavaScript’s event-driven architecture, resulting in better-performing applications.

That's all for today.

And also, share your favourite web dev resources to help the beginners here!

Connect with me:@ LinkedIn and checkout my Portfolio.

Explore my YouTube Channel! If you find it useful.

Please give my GitHub Projects a star ⭐️

Thanks for 22525! 🤗

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .