axios的then()/catch()链式调用,和async/await的方式,哪种好?选择哪种?

什么是链式调用

链式调用,其实就是前端开发中常见的.then()/.catch()这种形式来处理异步调用的方式。它是随着Promise的产生而产生的,要了解链式调用,就得先了解什么是Promise。就像下面这个简单示例:

axios.get('/xxx/xxx')
	.then(res=>{
		//处理调用成功时的结果
	})
	.catch(err=>{
		//调用失败时的处理
	})

什么是Promise?

它是一种风格

抽象地来说,它可以称为一种“风格”。因为它的出现改变了以前传统上处理异步操作的编程风格。原本在JavaScript中,是使用回调函数(callback)来处理异步操作的,而这种方式变得难以维护。尤其是遇到多层嵌套的回调时,容易出现“回调地狱”(callback hell)问题。
而Promise的诞生提供了我们所熟知的链式调用(即.then()和.catch()方式),来处理异步操作。这是一种新的风格,它有效地解决了回调嵌套问题,是的代码更加结构化。

它是一个对象

而具体地来说,它其实是JavaScript的一个表示异步操作的对象。它用于表示一个“此时已开始但未完成,但预计会在未来的某个时间完成”的操作,同时提供了链式调用这种结构化的方式来进行处理。
它有三种状态:

Pending(进行中): 初始状态,既不是成功也不是失败。
Fulfilled(已成功): 表示操作成功完成。
Rejected(已失败): 表示操作失败。

这三种状态是不可逆转的,一旦从一个状态跳到下一个状态,就不能再改变了。
它允许你注册回调函数,操作成功或失败时,会调用这些回调函数。
简单示例:

// 创建一个 Promise 实例
const myPromise = new Promise((resolve, reject) => {
  // 模拟一个异步操作(例如:网络请求)
  setTimeout(() => {
    const success = true; // 假设操作成功

    if (success) {
      resolve('操作成功!'); // 如果成功,调用 resolve
    } else {
      reject('操作失败!'); // 如果失败,调用 reject
    }
  }, 1000);
});

// 使用 .then() 和 .catch() 来处理结果和错误
myPromise
  .then(res=> {
    // 处理成功时的结果
  })
  .catch(err=> {
    // 处理错误
  });

什么是async/await?

自从Promise出现后,尽管解决了回调地狱的问题,但在写多个连续异步操作时,代码会变得冗长,让人难以阅读。
此时async/await就应运而生,ES8/ES2017引入了async/await。它的出现就是用来改善Promise的写法的,目的就是让代码变得更加直观易懂。可以说它是Promise的语法糖。

特点与使用方式

它的特点其实就在于async和await这两个关键字:

async 关键字: 用于声明一个函数为异步函数。异步函数会默认返回一个 Promise。
await 关键字: 用于暂停异步函数的执行,直到 Promise 被解决(resolved)或拒绝(rejected)。await 只能在 async 函数中使用。

async/await简单示例:

async function getData() {
  try {
  	//获取用户列表
    const res= await axios.get('/api/user/list');
    console.log('用户列表:', res.data);
	//获取某个具体的用户详情
    const userDetailRes= await axios.get(`/api/data/${res.data.get(0).id}`);
    console.log('用户详情:', userDetailRes.data);
  } catch (err) {
    console.error('错误:', err);
  }
}

getData();

以上写法改为链式调用则为:

axios.get('/api/user/list')
  .then(res => {
    console.log('用户列表:', res.data);
    // 返回一个新的 Promise 以便进行下一步的链式调用
    return axios.get(`/api/data/${res.data.get(0).id}`);
  })
  .then(userDetailRes=> {
    console.log('用户详情:', userDetailRes.data);
  })
  .catch(err=> {
     console.error('错误:', err);
  });

以上的代码,由于调用次数太少,可能无法很明显地体现复杂度的优化。
但可以看到,这种代码风格更加接近同步逻辑,其中try…catch是很常见的异常处理机制。一定程度上是优化了可读性。

哪种好?选择哪种?

总的来说,不能完全判断哪种更好,在实际使用还是可以按习惯或者项目要求来判断使用哪种方式。
而从产生背景来讲,async/await是优于链式调用的,因为它本身是Promise的优化。一般来说,嵌套层数较少时,两者区别可能并不大,但是如果遇到嵌套层数过多的情况,可以考虑使用async/await的风格来进行优化。
注意,由于async/await 是 ES8 (ES2017) 的特性,在一些旧的浏览器或者其他一些旧JavaScript运行环境中可能存在不支持的情况。
所以个人觉得,如果要考虑兼容性,可以优先考虑使用链式调用的方法就好。如果不需要考虑兼容性,可以优先使用async/await的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值