鸿蒙学习笔记(5)-HTTP请求数据

一、Http请求数据

http模块是鸿蒙内置的一个模块,提供了网络请求的能力。不需要再写比较原始的AJAS代码。

ps:在项目中如果要访问网络资源,不管是图片文件还是网络请求,必须给项目开放权限。

(1)网络连接方式

HTTP数据请求连接:通过HTTP发起的一个单向数据请求。

WebSocket连接:使用WebSocket建立服务器与客户端的双向连接。

Socket连接:通过Socket进行数据传输,更加底层。

(2)涉及接口文档

类型说明

http.createHttp()

创建一个HTTP请求,里面包括发起请求、中断请求、订阅/取消订阅HTTP Response Header事件。

HttpRequest()

根据URL地址,发起HTTP网络请求。

requestInStream()

根据URL地址,发起HTTP网络请求并返回流式响应,得到二进制数据,应用到文件下载,从后端拿到的不再是JSON和字符串,而是二进制数据。
destroy()中断请求任务。

(3)request接口开发步骤 

1、步骤概述

1、从@kit.NetworkKit中导入http命名空间。Kit是我们项目需要用到的各种服务,如网络服务,分布式管理服务,蓝牙通信等。

2、调用creatHttp()方法,创建一个HttpRequest对象。

3、调用该对象的request()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。(此步骤不是必须,是用来监控响应头信息,如果你想发请求给后端,想要先知道后端返回的数据是JSON还是文件之类的,可以用此监控,他会比内容先返回客户端。)

4、调用该对象的equest()方法,传入http请求的url地址和可选参数,发起网络请求。

5、得到结果过后,按照实际业务需要,解析返回结果,筛选或者进行数据转化。

6、调用该对象的off()方法,取消订阅http响应头事件。

7、当请求使用完毕时,调用destroy()方法主动销毁。

2、封装代码:

//在common模块中封装一个基础的请求工具import { http } from "@kit.NetworkKit";//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
export function MyRequest(url:string,method:http.RequestMethod,requestData:string){//2、创建http请求const httpRequest = http.createHttp()//3、可以用httprequest监听响应头(不是必须)httpRequest.on('headersReceive', (header: Object) => {console.info('header: ' + JSON.stringify(header));});httpRequest.request(url, {method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:requestData, //设置请求要传给后端的数据connectTimeout:9000,  //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data)}`)// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})
}

 3、使用说明:

在页面中要使用这个工具来测试请求是否成功,在common/index.ets文件中先暴露。

export  {MyRequest} from './src/main/ets/utils/HttpUtils'

在home页面或者组件中,引入对应的函数

import {MyRequest} from '@ohos/common'///比如跟事件绑定,测试数据是否能收到
.onClick((event:ClickEvent) => {MyRequest('http://47.98.128.191:4001/home/swiperdate',http.RequestMethod.GET,'')})

此时可以看到日志可以收到:

 此时请求发送完毕能够得到后端数据,但请求不是直接在页面或者组件中编写的代码,而是提取到了common模块中,如何拿到服务端的数据并显示到页面上,这才是需要解决的问题。

4、泛型编程

typescript中非常重要的一个概念:泛型编程

利用一个简单的案例:

function computed(params1:number,params2:number):number{return params1 +params2
}computed(1,3)//编译通过
computed('xiao','ming')//编译失败,因为只接受number类型

为了简化上面的代码,使代码更加灵活,尤其是在数据约束上,既要增加约束,又要让参数支持更多类型,或者更加灵活,设计方式便是采用泛型的方式来设计参数类型 。

function computed<T>(params1:T,params2:T):T{return params1 +params2
}computed<number>(1,3)   //编译通过
computed<string>('xiao','ming')   //编译通过
computed<bollean>(true,false)   //编译通过

同一个函数因为有了泛型,可以多次使用 ,这里我们以上面出现的问题:如何拿到服务端的数据并显示到页面上,利用promise来解决。通过promise对象将异步的请求代码封装到容器中获取到结果。

import { http } from "@kit.NetworkKit";
//BasicConstants下暴露基础URL地址,和传入的资源路径拼接
import { BasicConstants} from '../../constants/BasicConstants'
//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
export function MyRequest(url:string,method:http.RequestMethod,requestData:string){//2、创建http请求const httpRequest = http.createHttp()return new Promise((reslove:(value:string)=>void,reject:(value?:string)=>void)=>{//request发送请求就是异步代码httpRequest.request(//不再简单是url,而是做一下拼接基础地址BasicConstants.BASE_URL+url,{method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:requestData, //设置请求要传给后端的数据connectTimeout:9000,  //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data,null,2)}`)reslove(JSON.stringify(data))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)reject(JSON.stringify(error))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})})}

页面中获取请求返回的数据: 

 但此时传入参数是固定必须是string类型,不够灵活,接下来进一步封装,利用泛型编程做进一步优化使得代码实现复用。K代表请求的数据类型,T代表返回的数据类型

import { http } from "@kit.NetworkKit";
import { BasicConstants} from '../../constants/BasicConstants'
//封装请求代码,考虑到以后每个模块都要发送请求,默认放在common模块中。
//1、导入
//K代表请求的数据类型,T代表返回的数据类型
export function MyRequest<T,K>(url:string,method:http.RequestMethod,requestData?:K){//2、创建http请求const httpRequest = http.createHttp()return new Promise((reslove:(value:T)=>void,reject:(value?:string)=>void)=>{//request发送请求就是异步代码httpRequest.request(//不再简单是url,而是做一下拼接基础地址BasicConstants.BASE_URL+url,{method:method,//请求方式header:{//设置请求头//前端浏览器告诉后端,前端传递的数据格式'Content-Type': 'application/json'},extraData:JSON.stringify(requestData)||'', //设置请求要传给后端的数据connectTimeout:9000,  //前端发送数据给后端如果9秒没有结果,前端主动终止行为readTimeout:9000, //读取数据超过9秒,告诉前端请求失败},(error:Error,data:http.HttpResponse)=>{//error没有内容代表成功if (!error) {console.log(`请求成功,返回数据:${JSON.stringify(data,null,2)}`)//这里如何reslove(JSON.parse(data.result as string))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}else {console.log(`请求失败,具体原因:${JSON.stringify(error)}`)reject(JSON.stringify(error))// 取消订阅HTTP响应头事件。httpRequest.off('headersReceive');// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。httpRequest.destroy();}})})}

 页面中获取请求返回的数据: 

完整工具封装见资源文件。

(4)HTTP数据请求

4.1 导入HTTP模块

import http from '@ohos.net.http';


4.2 使用HTTP模块发送请求,处理响应.

4.2.1 创建一个http的请求对象,不可复用
const httpRequest = http.createHttp()
4.2.2 调用一个request方法,发起网络请求。

ps:像这种可能存在数据请求发送完但数据还没收到,因此此处方法执行完会存放一个未来会完成的结果Promise。

req.request('http://localhost:3000/users',//请求URL地址
{   //请求选项HttpRequestOptionsmetnod:http.RequestMethod.GET,extraData:{'param1':'value1'}    //k1=v1&k1=v2
}
)  
HttpRequestOptions 说明:
名称类型描述
methodRequestMethod请求方式,GET(查询)、POST(表单提交,新增)、PUT(修改)、DELETE(删除)等
extraDatastring|Object请求参数
headerObject请求头字段
connectTimeoutnumber请求超时时间,单位毫秒,默认60000ms
readTimeoutnumber读取超时间,同上


4.2.3 获取服务器响应的内容,Promise提供两种方法分别是then成功回调和catch失败回调。
.then((resp:http.HttpResponse)=>{if(resp.responseCode === 200){//请求成功}})
.catch((err:Error)=>{//请求失败
});
HttpResponse 说明: 
名称类型描述
responseCoderesponseCode响应状态码
headerObject响应头
cookiesstring响应返回的cookies
resultstring|Object响应体,默认是JSON字符串
resultTypeHttpDataType返回值类型

二、Promise

Promise是es6提出的一个概念,主要用来解决异步回调的问题。Promise是一个数据容器,保存了未来的一个结果,Promise本身是可以用来存放同步代码和异步代码,平时经常用来解决存放异步代码。以下是网络请求的一个发展历程:

发送网络请求,获取结果

1.1 发送网络请求

//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)
//浏览器默认提供的对象,获取结果
const xmlhttp = new XMLhttpRequest()
//连接服务器
xmlhttp.open('GET','http://+地址',true)
xmlhttp.send('id=1')//监听状态码,当状态码是200时
xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)}
}

1.2 将其封装工具

function ajas( {method='GET',url,data='',async=true} ){//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)//浏览器默认提供的对象,获取结果const xmlhttp = new XMLhttpRequest()//连接服务器xmlhttp.open(method,url,async)xmlhttp.send(data)//监听状态码,当状态码是200时xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)//这里return obj没有意义,这里是个事件,时间返回的函数外面是接收不到的}}
//如果在fuction函数这里return obj也是不可以的,局部的变量无法在外部用
}//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true
})

此时的obj还不能调出来使用,这时解决方法:在函数中在传入一个函数 success,如果函数能进入if中实现结果的取用,将在函数中调用。

function ajas( {method='GET',url,data='',async=true,success} ){//"AJAX"(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)//浏览器默认提供的对象,获取结果const xmlhttp = new XMLhttpRequest()//连接服务器xmlhttp.open(method,url,async)xmlhttp.send(data)//监听状态码,当状态码是200时xmlhttp.onreadystatechange = function(){//首先状态码必须是200,readyState代表xmlhttp加载过程if(xmlhttp.status == 200 && xmlhttp.readyState == 4){const result = xmlhttp.responseText//拿到数据后转化const obj = JSON.parse(result)success(Obj)}else if(404 500){error('失败')}}
}//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true,success:function(msg){console.log(msg)}//是否请求成功error:function(error){}   
})

 这样做有缺陷:回调地狱,无限制的在回调函数中执行任务,得到回调结果,层层嵌套,开发中要避免,不存在可读性。

//使用封装工具
ajax({method:'GET',url:'http://+地址',data:'id = 1'async:true,success:function(msg){console.log(msg)ajax({url:'http://+地址',data:msg.id,success(msg2){  ajax({url:'',data:msg.classesId}//是否请求成功error:function(error){}   
})

Promise

由上述Promise来解决异步编程的问题。 

//按照1234执行顺序来执行,因为promise本身是同步的,如果在promise中放入一个异步的代码,异步代码是需要花时间,异步代码不论花费多长时间,等到代码运行结束,成功或者失败都会存放在resolve,reject中。
console.log(1)
//resolve,reject 这两个参数是函数
const promise = new Promise((resolve,reject)=>{
console.log(2)//存放同步代码或者异步代码,这里主要存放异步代码ajas({url:'http://xxx',method:'POST',data:{id:1},success:(msg)=>{resolve(msg)},error:(error)=>{reject(error)}}) 
})//then这个函数是异步的,只有resolve执行完毕,then才会执行
promise.then((result)=>{console.log(4)
})
.catch(error=>{})console.log(3)

 await和async

es7提出的一个新方案,可以等待promise的结果。

//resolve,reject 这两个参数是函数
const promise2 = new Promise((resolve,reject)=>{//存放同步代码或者异步代码,这里主要存放异步代码ajas({url:'http://xxx',method:'POST',data:{id:1},success:(msg)=>{resolve(msg)},error:(error)=>{reject(error)}}) 
})async function show(){const res1 = await promise1const res2 = await promise2
}

 axios工具

在前面代码的基础上,第三方工具axios做了一件事情,将axios代码和promise代码进行了封装,形成了一个完整的请求工具。

//封装格式
class Axios{baseURL =''get(){return new Promise (()=>{resolve(xxx)reject(xxx)})}post(){}creat(){}
}export const axios = new Axios()//代码中如何使用
import axios from 'axios'
//方法1:通过then拿到服务器响应回来的结果
axios.get('http://xxx').then(res=>{{)
//方法2:通过await和async配合拿到服务器响应回来的结果
result = await axios.post('http://xxx')

作为一个第三方库,使用的时候需要先完成下包的操作,打开终端执行命令,ohpm 是一个包管理工具,用来管理鸿蒙提供的第三方模块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76437.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Redis5.X部署一个集群

文章目录 1.用Redis5.x来创建Cluste2. 查看节点信息 nodes3. 添加节点 add-node4.删除节点 del-node5.手动指定从节点 replicate6.检查集群健康状态 check 建议使用5.x版本。 首先&#xff0c;下载Redis&#xff0c;根据自己的环境选择版本。 一键启动Redis集群文件配置。 ech…

实现窗口函数

java 实现窗口函数 public class SlidingWin {public static void main(String[] args) {SlidingWin slidingWin = new SlidingWin();double v = slidingWin.SlidWin(2);System.out.println(v);}public double SlidWin(int k){int [] array =new int[]{2,4,5,6,9,10,12,23,1,…

Docker Compose 命令实现动态构建和部署

Docker Compose 命令实现动态构建和部署 一、编写支持动态版本号的 docker-compose.yml version: 3.8services:myapp:build: context: . # Dockerfile所在目录args:APP_VERSION: ${TAG:-latest} # 从环境变量获取版本号&#xff0c;默认latestimage: myapp:${TAG:-latest} …

AI时代下 你需要和想要了解的英文缩写含义

在AI智能时代下&#xff0c;越来愈多的企业都开始重视并应用以及开发AI相关产品&#xff0c;这个时候都会或多或少的涉及到英文&#xff0c;英文还好&#xff0c;但是如果是缩写&#xff0c;如果我们没有提前了解过&#xff0c;我们往往很难以快速Get到对方的意思。在这里&…

聊聊Doris的数据模型,如何用结构化设计解决实时分析难题

传统 OLAP 系统的局限 在大数据实时分析领域&#xff0c;数据模型设计直接决定了系统的查询性能、存储效率与业务适配性。Apache Doris作为新一代MPP分析型数据库&#xff0c;通过独创的多模型融合架构&#xff0c;在业内率先实现了"一份数据支持多种分析范式"的能力…

基于vue框架的点餐系统设计及实现w93q6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,菜品分类,菜品信息,配送员,订单信息,配送进度,评价记录 开题报告内容 基于 Vue 框架的点餐系统设计及实现开题报告 一、研究背景与意义 &#xff08;一&#xff09;研究背景 在当今快节奏的生活中&#xff0c;网上订餐已成为人…

LeetCode 2563.统计公平数对的数目:排序 + 二分查找

【LetMeFly】2563.统计公平数对的数目&#xff1a;排序 二分查找 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-the-number-of-fair-pairs/ 给你一个下标从 0 开始、长度为 n 的整数数组 nums &#xff0c;和两个整数 lower 和 upper &#xff0c;返回 公平…

CF1016赛后总结

文章目录 前言T1:Ideal GeneratorT2&#xff1a;Expensive NumberT3:Simple RepetitionT4&#xff1a;Skibidi TableT5:Min Max MEXT6:Hackers and Neural NetworksT7:Shorten the Array 前言 由于最近在半期考试&#xff0c;更新稍微晚了一点&#xff0c;还望大家见谅 &#…

HFSS3(limy)——建模学习记录

前言——笔者使用的是21版HFSS 1.基本模型 为什么没有环形的天线 2.创建基本模型方法 常用&#xff1a;先粗略建好模型再编辑输入准确坐标和大小尺寸&#xff08;这里长方体起始点是左上角下方的点&#xff0c;也就是说要输入模型起点相对于坐标原点的位置尺寸就可以确定具体…

API网关的作用?企业如何应用API网关?

一、API网关的用处 API网关我的分析中会用到以下三种场景。 1、Open API 企业需要将自身数据、能力等作为开发平台向外开放&#xff0c;通常会以rest的方式向外提供。最好的例子就是淘宝开放平台、腾讯公司的QQ开发平台、微信开放平台。 Open API开放平台必然涉及到客户应用…

国网B接口协议图像数据上报通知接口流程详解以及上报失败原因(电网B接口)

文章目录 一、B接口协议图像数据上报通知接口介绍B.13.1 接口描述B.13.2 接口流程B.13.3 接口参数B.13.3.1 SIP头字段B.13.3.2 SIP响应码B.13.3.3 XML Schema参数定义 B.13.4 消息示例B.13.4.1 图像数据上报请求B.13.4.2 图像数据上报响应 二、B接口图像数据上报通知失败常见问…

springAi---智能客服

首先被取代的是客服类&#xff0c;智能客服机器人都能够高效地完成任务。 spring Ai 大模型应用相关开发demo&#xff0c;智能客服系统&#xff1b; 在需求分析阶段&#xff0c;把功能属于传统Java处理的和ai的功能进行分离 梳理为流程图如下&#xff1a; 在大模型中&#…

Java面试(2025)——基础

Java语言有哪些特点&#xff1f; Java语言具有多个显著特点&#xff0c;使其在编程领域广受欢迎。首先&#xff0c;Java的跨平台性非常强&#xff0c;通过Java虚拟机&#xff08;JVM&#xff09;实现“编写一次&#xff0c;随处运行”&#xff0c;使得开发者能够在不同操作系统…

Linux压缩与解压命令完全指南:tar.gz、zip等格式详解

Linux压缩与解压命令完全指南&#xff1a;tar.gz、zip等格式详解 在Linux系统中&#xff0c;文件压缩和解压是日常操作中不可或缺的一部分。本文将全面介绍Linux下常用的压缩和解压命令&#xff0c;包括tar.gz、tar、zip等格式的区别和使用方法&#xff0c;帮助你高效管理文件…

C++ STL 环形队列模拟实现

C STL 环形队列模拟实现 下面是一个使用C STL实现的环形队列&#xff08;Circular Queue&#xff09;的完整示例&#xff1a; #include <iostream> #include <vector> #include <stdexcept>template <typename T> class CircularQueue { private:std…

部署rocketmq集群

容器化部署RocketMQ5.3.1集群 背景: 生产环境单机的MQ不具有高可用,所以我们应该部署成集群模式,这里给大家部署一个双主双从异步复制的Broker集群 一、安装docker yum install -y docker systemctl enable docker --now # 单机部署参考: https://www.cnblogs.com/hsyw/p/1…

mysql的函数(第一期)

一、字符串函数​​ 处理文本数据&#xff0c;常用函数&#xff1a; ​​CONCAT(str1, str2, ...)​​ ​​作用​​&#xff1a;拼接字符串。​​示例​​&#xff1a;SELECT CONCAT(Hello, , World); → Hello World​​注意​​&#xff1a;若任一参数为 NULL&#xff0c;…

Linux下的网络管理

注意&#xff1a;本文使用的Linux系统版本为Red Hat Enterprise Linux 9 (RHEL 9)。 在RHEL9上&#xff0c;使用NM&#xff08;NetworkManager&#xff09;进行网络配置&#xff0c;ifcfg &#xff08;也称为 文件&#xff09;将不再是网络配置文件的主存储。虽然 ifcfg 样式仍…

游戏引擎学习第233天

原地归并排序地方很蒙圈 game_render_group.cpp&#xff1a;注意当前的SortEntries函数是O(n^2)&#xff0c;并引入一个提前退出的条件 其实我们不太讨论这些话题&#xff0c;因为我并没有深入研究过计算机科学&#xff0c;所以我也没有太多内容可以分享。但希望在过去几天里…

从《周游记3》演绎歌剧版《菊花台》,周杰伦婚礼曲目意大利文版惊喜亮相

今天&#xff08;4月19日&#xff09;22:00&#xff0c;由魔胴西西里咖啡冠名的户外实境互动综艺《周游记3》第四期即将播出。本期节目中&#xff0c;“J式之旅”发起人周杰伦和林暐恒、杜国璋、陈冠霖、陈冠廷&#xff0c;将继续意大利之旅&#xff0c;从那不勒斯的百年老店到…