使用async/await解决fetch

本文探讨了使用fetch进行网络请求时的实现细节,包括如何正确处理返回数据及错误情况。并通过对比传统的.then链式调用,展示了async/await语法糖带来的代码优化效果。

title: fetch/async/await
date: 2022-08-11 22:23:55
tags:

  • es6
  • fetch
  • async/await
  • React
    categories:
  • JS

fetch和await的结合

起因是在写一个React发送ajax请求的案例中,遇到了一个关于fetch发送请求的问题,直接上代码:

使用fetch发送请求后在第一个.then之前的fetch(https:xxxx//${value})返回的是一个promise实例对象,所以它的后面可以跟.then,但是这个.then中触发的成功回调或者失败回调仅仅是判断这个请求是否连接到服务器,并不会返回服务器发送回来的数据。

要想得到数据就需要调用res原型上的方法res.json()得到一个新的promise,并且return出去,紧跟后面的.then就可以采用链式.then的方法再次获得成功的回调(服务器返回的数据在里面)。

  search = ()=>{
// 使用fetch发送网络请求(未优化版本)
    fetch(`https://api.github.com/search/users?q=${value}`).then(
      res=>{
        console.log('联系服务器成功');
        return res.json();
      },
      // error=>{
      //   console.log('联系服务器失败');
      //   // 如果第一个then没有返回值,那么它会返回一个undefined,
      //   // 而undefined所在的.then返回的promise则是一个成功状态的promise
      //   // 使用return new Promise();返回一个初始状态的Promise实例,则下面的then则不会走了
      //   return new Promise();
      // }
    ).then(
      ress=>{
        // console.log(ress.items);
        PubSub.publish('change',{isFirst:false,users:ress.items,isLoading:false})
      },
      // error=>{
      //   console.log('获取数据失败');
      //   PubSub.publish('change',{isFirst:false,err:error.message})
      // }
    ).catch((error)=>{
      console.log(error);
    })
  }

当然可以不用每个.then都捕获错误回调,可以在结尾统一拦截错误使用.catch()

还有一个小bug就是,如果在第一个.then中的错误回调没有返回一个promise或者其他什么的,他会默认返回undefined,而这个undefined则代表其所在.then返回的是一个成功状态的promise,这就导致后面的.then执行的是成功回调。


然后再说说async和await优化版本:

使用async和await可以更大限度优化代码,

等待fetch(https://api.github.com/search/users?q=${value})返回一个成功态promise给response,response接收到后调用它原型上的方法response.json()当然也要等待它返回一个成功态promise,并将其赋值给data,此时的data就是服务器返回的真正数据

另外,捕获错误可以使用try-catch捕获错误

这种写法可以使用同步执行的思考来看待这个请求,对于promise的理解更深一步加强

search = async ()=>{
    // 解构赋值的连续写法
    // keyWordElement是未被定义的
    const {keyWordElement:{value}}=this
    // 发送请求前通知List更新状态
    PubSub.publish('change',{isFirst:false,isLoading:true})//不用关注

    try {
      const response = await fetch(`https://api.github.com/search/users?q=${value}`)
      const data = await response.json();
      // console.log(data);//服务器返回的真正数据
      PubSub.publish('change',{isFirst:false,users:data.items,isLoading:false})
    } catch (error) {
      console.log('请求出错',error);
      PubSub.publish('change',{isFirst:false,err:error.message})
    }
  }
在 Vue.js 中使用 `async/await` 处理 Fetch 请求是一种现代且高效的方式,能够简化异步代码的逻辑结构,并提高代码的可读性和可维护性。通过将 `fetch` 请求封装在 `async` 函数中,并结合 `try...catch` 语句块进行错误处理,可以更清晰地控制异步流程。 以下是一个在 Vue 组件中使用 `async/await` 发起 Fetch 请求并处理响应的完整示例: ```javascript export default { data() { return { items: [], error: null }; }, async mounted() { try { const response = await fetch('https://api.example.com/items'); if (!response.ok) { throw new Error('网络响应失败'); } const data = await response.json(); this.items = data; } catch (err) { this.error = err.message; console.error('请求过程中发生错误:', err); } } }; ``` 在这个示例中,`mounted` 生命周期钩子被定义为 `async` 函数,以便在其内部使用 `await` 等待 `fetch` 请求的响应。通过两次 `await` 调用分别获取响应对象和解析 JSON 数据,避免了传统的嵌套 `.then()` 回调结构。同时,使用 `try...catch` 块可以捕获任何在请求过程中发生的错误,包括网络错误或非 200 响应状态码。 此外,在实际开发中建议对错误进行分类处理,例如区分网络错误和业务逻辑错误。也可以将 Fetch 请求封装到单独的服务模块中,以实现更好的职责分离和代码复用。例如: ```javascript // services/api.js export default { async fetchData(url) { const response = await fetch(url); if (!response.ok) { throw new Error(`请求失败,状态码: ${response.status}`); } return await response.json(); } } ``` 然后在 Vue 组件中调用该服务: ```javascript import api from '@/services/api'; export default { data() { return { data: null, error: null }; }, async created() { try { this.data = await api.fetchData('https://api.example.com/data'); } catch (err) { this.error = err.message; } } }; ``` 这种方式不仅提高了代码的模块化程度,也便于进行单元测试和统一的错误处理策略。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值