什么是回调地狱?

回调地狱通常表现为以下特点:

代码嵌套严重:每个异步操作通常都有一个回调函数来处理其结果,当这些操作需要按顺序执行时,回调函数会一层层地嵌套,形成金字塔形状的代码结构。
难以维护:回调地狱中的代码结构复杂,难以追踪和维护,尤其是当需要修改逻辑或添加新的功能时。
错误处理困难:在嵌套的回调函数中处理错误变得非常棘手,因为每次异步操作都需要显式地在回调中添加错误处理逻辑。

setTimeout(function () { //第一层
    console.log('111111111');
    setTimeout(function () { //第二层
        console.log('2222222');
        setTimeout(function () { //第三层
            console.log('3333333333');
        }, 1000)
    }, 2000)
}, 3000)

在这里插入图片描述
在这里插入图片描述

解决 回调地狱 使用 Promise 和 async/await (是promise的语法糖)进行优化

await async promise
await async promise

方法一:Promise 链式调用 (Promise Chaining)

这种方法将每个异步操作封装成一个返回 Promise 的函数,然后用 .then() 将它们串联起来。

// 1. 创建一个返回Promise的延时函数,是通用的解决方案
function delay(ms, message) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(message);
      resolve(); // 打印完成后解析Promise,通知链可以继续了
    }, ms);
  });
}

// 2. 使用Promise链式调用
delay(3000, '11111111')
  .then(() => delay(2000, '2222222222'))
  .then(() => delay(1000, '333333333'))
  .then(() => {
    console.log('xxxxxxx');
  })
  .catch((error) => {
    // 只需要一个catch就可以捕获链中任何一步的错误
    console.error('出了点问题:', error);
  });
方法二:Async/Await (推荐)

这是最简洁、最像同步代码的写法,可读性极高。

// 1. 创建一个返回Promise的延时函数,是通用的解决方案
async function delay(ms, message) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(message);
      resolve(); // 打印完成后解析Promise,通知链可以继续了
    }, ms);
  });
}

// 2. 创建一个async函数来包裹所有异步操作
async function martialArtsTeachings() {
  try {
    await delay(3000, '111111');
    await delay(2000, '2222222');
    await delay(1000, '33333333');
    console.log('XXXXXX');
  } catch (error) {
    // 统一错误处理
    console.error('ERRROR:', error);
  }
}

// 执行这个函数
martialArtsTeachings();

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐