Implementing Standard Practices for Asynchronous Callback Handling

Define best practices for managing asynchronous callbacks to improve readability and minimize callback hell.

0 likes
39 views

Rule Content

{
  "title": "Implementing Standard Practices for Asynchronous Callback Handling",
  "description": "Define best practices for managing asynchronous callbacks to improve readability and minimize callback hell.",
  "category": "JavaScript Cursor Rules",
  "rules": [
    {
      "name": "Avoid Nested Callbacks",
      "description": "To prevent callback hell, avoid nesting multiple callbacks. Instead, use Promises or async/await syntax to flatten the code structure.",
      "examples": {
        "bad": "fs.readFile('file1.txt', (err, data1) => {\n  if (err) throw err;\n  fs.readFile('file2.txt', (err, data2) => {\n    if (err) throw err;\n    fs.readFile('file3.txt', (err, data3) => {\n      if (err) throw err;\n      console.log(data1, data2, data3);\n    });\n  });\n});",
        "good": "const readFiles = async () => {\n  try {\n    const data1 = await fs.promises.readFile('file1.txt');\n    const data2 = await fs.promises.readFile('file2.txt');\n    const data3 = await fs.promises.readFile('file3.txt');\n    console.log(data1, data2, data3);\n  } catch (err) {\n    console.error(err);\n  }\n};\nreadFiles();"
      }
    },
    {
      "name": "Use Promises for Asynchronous Operations",
      "description": "Utilize Promises to handle asynchronous operations, allowing for cleaner and more maintainable code through chaining and centralized error handling.",
      "examples": {
        "bad": "function fetchData(callback) {\n  setTimeout(() => {\n    callback('Data fetched!');\n  }, 1000);\n}\nfetchData((data) => {\n  console.log(data);\n});",
        "good": "const fetchData = () =>\n  new Promise((resolve) => {\n    setTimeout(() => resolve('Data fetched!'), 1000);\n  });\nfetchData()\n  .then((data) => console.log(data))\n  .catch((error) => console.error(error));"
      }
    },
    {
      "name": "Prefer Async/Await Syntax",
      "description": "Use async/await syntax for asynchronous code to improve readability and maintainability, making it appear more like synchronous code.",
      "examples": {
        "bad": "function fetchData() {\n  return fetch('https://api.example.com/data')\n    .then((response) => response.json())\n    .then((data) => console.log(data))\n    .catch((error) => console.error(error));\n}\nfetchData();",
        "good": "const fetchData = async () => {\n  try {\n    const response = await fetch('https://api.example.com/data');\n    const data = await response.json();\n    console.log(data);\n  } catch (error) {\n    console.error(error);\n  }\n};\nfetchData();"
      }
    },
    {
      "name": "Handle Errors Properly in Asynchronous Code",
      "description": "Implement error handling mechanisms such as try/catch blocks in async functions or .catch() in Promises to manage errors gracefully.",
      "examples": {
        "bad": "const fetchData = async () => {\n  const response = await fetch('https://api.example.com/data');\n  const data = await response.json();\n  console.log(data);\n};\nfetchData();",
        "good": "const fetchData = async () => {\n  try {\n    const response = await fetch('https://api.example.com/data');\n    const data = await response.json();\n    console.log(data);\n  } catch (error) {\n    console.error('Error fetching data:', error);\n  }\n};\nfetchData();"
      }
    },
    {
      "name": "Use Promise.all for Concurrent Operations",
      "description": "When multiple asynchronous operations can run concurrently, use Promise.all to improve performance by executing them in parallel.",
      "examples": {
        "bad": "const fetchData1 = async () => {\n  const response = await fetch('https://api.example.com/data1');\n  return response.json();\n};\nconst fetchData2 = async () => {\n  const response = await fetch('https://api.example.com/data2');\n  return response.json();\n};\nconst fetchAllData = async () => {\n  const data1 = await fetchData1();\n  const data2 = await fetchData2();\n  console.log(data1, data2);\n};\nfetchAllData();",
        "good": "const fetchData1 = async () => {\n  const response = await fetch('https://api.example.com/data1');\n  return response.json();\n};\nconst fetchData2 = async () => {\n  const response = await fetch('https://api.example.com/data2');\n  return response.json();\n};\nconst fetchAllData = async () => {\n  try {\n    const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);\n    console.log(data1, data2);\n  } catch (error) {\n    console.error('Error fetching data:', error);\n  }\n};\nfetchAllData();"
      }
    }
  ]
}