ArkTs封装网络请求并发起一个Get请求

文章概叙

本文讲的是封装下ArkTs的HTTP请求,做一下公共的拦截,并使用这个lib发起一次请求。

封装的重要性

出来混的,封装一个lib已经是一个必备的技能了,尤其是做前端开发的,哪个HTTP请求不需要做统一的拦截处理呢,所以,今天除了介绍下ArkTs中的HTTP请求之外,还会说一下如何封装一个HTTP请求,以便做统一拦截

HTTP请求

贪多嚼不烂,第一步我们需要先了解下ArkTs中的HTTP请求是怎么样的,又有哪一些步骤,而不是直接一上来就丢出一个例子,跟人说你已经封装好了,不然人家一问三不知。

准备工作

需要下面的权限,文件的路径贴在了下面,申请权限这一块按下不表,因为不是重点。

src/main/module.json5

requestPermissions:[
  {
    "name" : "ohos.permission.INTERNET"
  }
]

接下来,就按照官网上的request接口开发步骤,使用http请求。
在这里插入图片描述

创建实例

import http from ‘@ohos.net.http’;

第一步的引入,我们并不需要手动去写那么一行代码,当我们第二步创建一个http实例的时候,开发工具会自动帮我们引入这个包,结合上一篇博客,我们需要在页面的aboutToAppear方法中创建,代码如下:

import http from '@ohos.net.http';
​
@Entry
@Component
export struct Found {
  aboutToAppear() {
    const httpRequest = http.createHttp();
    console.log("当前调用了aboutToAppear方法");
  }build() {}
}

获取返回体数据

由于获取订阅http响应头事件在前端的用处不大,所以暂时跳过,文章的后面将其与取消订阅http响应头事件一起说。

创建好了示例,自然是要设置请求参数了,为了方便,这儿直接设置Url为百度,且设置请求的方式为Get请求。则代码编写如下:

  aboutToAppear() {
    const httpRequest = http.createHttp();
    httpRequest.request(
      "https://www.baidu.com",
      {
        // 设置为get请求
        method:http.RequestMethod.GET,
      }
    )
  }

当前由于只有一个最简单的get请求,所以只需要传入地址以及请求方式,而其他的参数的描述,按照官网,粘贴如下:
在这里插入图片描述

其中最重要的,自然就是我们的header以及extraData。

使用Asyn-Await优化

至此,一个请求是发出去了,接下来就是获取消息了,但是官网上的方式是如下

httpRequest.request(url,params,callback)

站在前端开发的基础上,我们自然可以使用Async-Await优化了,所以代码如下:

  async aboutToAppear() {
    const httpRequest = http.createHttp();
    const data = await httpRequest.request(
      "https://www.baidu.com/s?ie=UTF-8&wd=ArkTs%E5%B0%81%E8%A3%85%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E5%B9%B6%E5%8F%91%E8%B5%B7%E4%B8%80%E4%B8%AAGet%E8%AF%B7%E6%B1%82",
      {
        // 设置为get请求
        method: http.RequestMethod.GET,
      }
    )
    console.log("data====================>");
    console.log(JSON.stringify(data.result));
    console.log(JSON.stringify(data.cookies))
    console.log(JSON.stringify(data.responseCode))
  }

返回的内容在控制台打印如下,各位可以对号入坐。
在这里插入图片描述

为了方便以及验证官网上所说的,还有err以及resoponse是什么,我们将路径修改下

"https://www.abc123def456.com"

请耐心听我的废话,因为我们做拦截器的时候,对这些错误要有了解.
在这里插入图片描述

而我们既然用了Async-Await,那么错误拦截就必须要放在catch中,所以我们可以这么处理。

  const data:any = await httpRequest.request(
      // "https://www.aidu.com/s?ie=UTF-8&wd=ArkTs%E5%B0%81%E8%A3%85%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E5%B9%B6%E5%8F%91%E8%B5%B7%E4%B8%80%E4%B8%AAGet%E8%AF%B7%E6%B1%82",
      "https://www.abc123def456.com",
      {
        // 设置为get请求
        method: http.RequestMethod.GET
      }
    ).catch((err:any)=>{
      console.log("出现错误了!!!!!");
      console.log(JSON.stringify((err)));
      Promise.reject(err);
    })

返回的结构如下:

在这里插入图片描述

也就是说我们的错误原因是地址写错了,所以无法找到这个服务器。

即然如此,我们就可以封装下,将返回的错误统一成500,不建议根据每个code去查询是什么bug,建议直接设置一个状态码以及打印出日志。

按照这个思路,我们的代码如下:

   const data:any = await httpRequest.request(
      "https://www.abc123def456.com",
      {
        // 设置为get请求
        method: http.RequestMethod.GET
      }
    ).catch((err:any)=>{
      console.log("出现错误了!!!!!");
      return ({"responseCode":500,result:err.message});
    })
    console.log("data====================>");
    console.log(JSON.stringify(data?.result));
    console.log(JSON.stringify(data?.cookies))
    console.log(JSON.stringify(data?.responseCode))
  }

需要注意的是,第九行中我直接将结构体returen出去,这样子我们才能在下面拦截到数据。
具体需要怎么操作,哪些字段,建议看自己的项目来设置返回体。
关闭http请求

第六步依旧涉及到“订阅http响应头事件”,按下不表,继续看第七步的httpRequest.destroy();

由于我们已经用了Async-Await了,所以我们就直接在最后加上这一个就可以了,不需要说再在error的时候分别添加

一般来说,开发都不怎么需要关闭http请求,因为接受完数据后,我们的http通道都会自动关闭,但是鸿蒙要求我们手动关闭,所以我们最好听人劝,吃饱饭。

 async aboutToAppear() {
    const httpRequest = http.createHttp();
    const data:any = await httpRequest.request(
      "https://www.abc123def456.com",
      {
        // 设置为get请求
        method: http.RequestMethod.GET
      }
    ).catch((err:any)=>{
      console.log("出现错误了!!!!!");
      return ({"responseCode":500,result:err.message});
    })
    //关闭请求
    httpRequest.destroy();
    console.log("data====================>");
    console.log(JSON.stringify(data?.result));
  }

HTTP Response Header 事件

Response Header 顾名思义,就是请求返回的header接收到的时候,可以直接在这处理,但是我们一般用的比较少,因为相比之下,我们更需要的是body的内容。
在返回头中,最主要是做空值判断,比如当页面返回的是null,也就是请求头中会设置字节数为0,这个时候就可以跳过对我们请求的处理了

虽然用的不多,但是照例写一下。

 httpRequest.on('headersReceive', (header) => {
      console.info('这个是headersReceive事件');
    });

但是很可惜…

在这里插入图片描述

在请求失败的情况下,没有header返回,这也是我比较少用的原因…
封装

即然现在对于HTTP请求已经熟悉了,我们就可以封装了,而刚其实也封装的差不多了,只是我们可以再加一个Promise.

代码如下:

  async getHttp(url: string, method: http.RequestMethod, body?: any) {
    return new Promise(async (resolve, reject)=>{
      const httpRequest = http.createHttp();
      const data: any = await httpRequest.request(
        url,
        {
          // 设置为get请求
          method,
          extraData:body?body:undefined
        }
      ).catch((err: any) => {
        console.log("出现错误了!!!!!");
        return ({ "responseCode": 500, result: err.message });
      })
      //关闭请求
      httpRequest.destroy();
      console.log("data====================>");
      console.log(JSON.stringify(data?.result));
      resolve(data);
    }
    )
  }

其中,有几个点是需要讲一下

  • 定义到使用的过程,是定义一次,完成一次之后就销毁的

  • 代码中的body,如果没有传的时候,是传过去undefined,自动会被忽略掉,同理,header也可以设置一个默认的。或者是直接修改request的第二个参数.

  • 因为async/await返回的是promise。所以有可能会导致页面卡断,但是这个可以忽略不计!

测试

接下来,写一个For循环请求测试下。

 async aboutToAppear() {
    let num = [1, 2, 3, 4, 5];
    for (let i in num) {
      const data = await this.getHttp(
      "https://www.baidu.com", 
      http.RequestMethod.GET);
    }
  }

使用for循环的原因是因为可以跟Async-Await 搭配使用,效果如下:

在这里插入图片描述

可以看到,好一个整齐划一的日志!!

封装结束。其实有javasxcipe开发经验的都可以知道我的思路,基本就是封装Axios那一套,所以大家不用太紧张,Async-Await用的好就可以了。
最后,一般我们会将其封装成一个为文件,这个看人而已。

在这里插入图片描述
公众号文章链接

主要介绍前端开发的博客,由衷期望各位大佬们扫码关注