Ajax + Promise复习简单小结simple

news2024/12/26 1:03:22

axios使用

先看看老朋友 axios
axios是基于Ajax+promise封装的
看一下他的简单使用
安装:npm install axios --save
引入:import axios from 'axios'

GitHub地址

基本使用

axios({url: 'http://hmajax.itheima.net/api/province'}).then(function (result) {
		const {data: {list, message}, status} = result
		console.log(list, message, status)
})
// 发送 GET 请求(默认的方法)
axios('/user/12345').then(response => {}).catch(error => {})

查询参数

axios({
	url: 'http://hmajax.itheima.net/api/city',
	method: 'get',
	params: {
		pname: '河南省'
	}
}).then(function (result) {
	// const {data: {list, message}, status} = result
	console.log(result)
})

post提交

document.querySelector('button').addEventListener('click', function () {
	axios({
		url: 'http://hmajax.itheima.net/api/register',
		method: 'post',
		data: {
			username: 'itheima123',
			password: '123456'
		}
	}).then(function (result) {
		console.log(result)
	})
})

错误处理

document.querySelector('button').addEventListener('click', function () {
		axios({
			//请求选项
			url: 'http://hmajax.itheima.net/api/register',
			method: 'post',
			data: {
				username: 'itheima123',
				password: '123456'
			}
		}).then(function (result) {
			//处理数据
			console.log(result)
		}).catch(function (error) {
			//处理错误
			console.log(error.response.data.message)
		})
	})

实现一个简单地图片上传在这里插入图片描述

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<style>
		img {
			height: 200px;
			width: auto;
			border-radius: 20px;
			border: 1px solid rebeccapurple;
		}
	</style>
</head>
<body>
<input type="file" class="upload">
<img/>
</body>
<script type="text/javascript" src="../js/axios.js"></script>
<script type="text/javascript">
	/*
	* 图片上传显示在网页上面
	* 1. 获取图片文件
	* 2. 使用 FormData 携带图片文件
	* 3. 提交到服务器获取到返回的图片服务器地址*/
	document.querySelector('input').addEventListener('change', function (e) {
		console.log(e.target.files[0])
		//FormData对象
		const fd = new FormData()
		fd.append('img', e.target.files[0])
		axios({
			url: 'http://hmajax.itheima.net/api/uploadimg',
			method: 'post',
			data: fd
		}).then(function (result) {
			console.log(result)
			document.querySelector('img').src = result.data.data.url
		}).catch(function (error) {
			console.log(error)
		})
	})
</script>
</html>

XMLhttpRequest使用

/*get请求携带参数*/
/*1. 实例化一个xhr对象*/
const xhr = new XMLHttpRequest()
/*2. 配置请求方法和URL地址*/
xhr.open('get', 'http://hmajax.itheima.net/api/city?pname=辽宁省')
/*3. 添加load事件,获取响应结果*/
xhr.addEventListener('load', function (result) {
	console.log(JSON.parse(result.target.response))
	document.write(JSON.parse(result.target.response).list.join(' , '))
})
/*4. 发起请求*/
xhr.send()
	
/*post请求设置请求头,携带请求体*/
document.querySelector('button').addEventListener('click', () => {
	const xhr = new XMLHttpRequest()
	xhr.open('post', 'http://hmajax.itheima.net/api/register')
	xhr.addEventListener('load', function (result) {
		console.log(JSON.parse(result.target.response))
	})
	/*设置请求头 告诉服务器 内容类型*/
	xhr.setRequestHeader('Content-Type', 'application/json')
	const user = {username: 'itheima093', password:' 123456'}
	const userStr = JSON.stringify(user)
	/*将字符串类型的 请求体发送给服务器*/
	xhr.send(userStr)
})

详细文档参照 MDN

同步异步

  • 同步代码
    • 逐行执行,原地等待结果后,才继续向下执行
  • 异步代码
    • 调用后耗时,不阻塞代码执行,将来完成后触发回调函数

JavaScript中的异步代码有
- setTimeout / setInterval
- 事件
- Ajax

异步代码接收结果!
- 依靠异步的回调函数接收结果

回调地狱

在回调函数中一直向下嵌套回调函数,就会形成回调函数地狱

/*毁掉地狱*/
	new MyAxios({
		url: 'http://hmajax.itheima.net/api/province'
	}).then(result => {
		console.log(result)
		let province = document.querySelector('.province')
		province.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
		new MyAxios({
			url: 'http://hmajax.itheima.net/api/city',
			params: {pname: province.value}
		}).then(result => {
			console.log(result)
			let city = document.querySelector('.city')
			city.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
			new MyAxios({
				url: 'http://hmajax.itheima.net/api/area',
				params: {pname: province.value, cname: city.value}
			}).then(result => {
				console.log(result)
				let area = document.querySelector('.area')
				area.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
			})
		})
	})

缺点:
- 可读性差
- 异常捕获困难
- 耦合性严重

解决:
promise的链式调用
使用then函数返回新的Promise对象的特性一直串联下去

/*链式调用*/
	let province = document.querySelector('.province')
	new MyAxios({url: 'http://hmajax.itheima.net/api/province'}).then(result => {
		console.log(result);
		province.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
		return new MyAxios({url: 'http://hmajax.itheima.net/api/city', params: {pname: province.value}})
	}).then(result => {
		console.log(result);
		let city = document.querySelector('.city');
		city.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
		return new MyAxios({url: 'http://hmajax.itheima.net/api/area', params: {pname: province.value, cname: city.value}})
	}).then(result => {
		console.log(result);
		let area = document.querySelector('.area');
		area.innerHTML = result.list.map(item => `<option>${item}</option>`).join('')
	})

使用async 和 await解决(最优)

/*async await 配合使用*/
async function init() {
	let province = document.querySelector('.province')
	let city = document.querySelector('.city');
	let area = document.querySelector('.area');
	console.log('开始执行异步代码')
	/*错误捕获; try 代码块中出现了错误,代码就不会继续往下执行了*/
	try {
		const provinceList = await new MyAxios({url: 'http://hmajax.itheima.net/api/province'})
		province.innerHTML = provinceList.list.map(item => `<option>${item}</option>`).join('')
		const cityList = await new MyAxios({url: 'http://hmajax.itheima.net/api/city', params: {pname: province.value}})
		city.innerHTML = cityList.list.map(item => `<option>${item}</option>`).join('')
		const areaList = await new MyAxios({url: 'http://hmajax.itheima.net/api/area', params: {pname: province.value, cname: city.value}})
		area.innerHTML = areaList.list.map(item => `<option>${item}</option>`).join('')
		console.log(provinceList)
		console.log(cityList)
		console.log(areaList)
	}catch (error) {
		console.dir(error)
	}finally {
		console.log('finally')
	}
}

Promise

Promise 对象表示异步操作最终的完成(或失败)以及其结果值。

三个状态:
pending (初始状态,既没有兑现也没有拒绝) => fulfilled(操作成功) / rejected(操作失败)
Promise对象一旦被兑现或拒绝,就代表该对象就已敲定了,状态将无法在改变

优点:

  • 逻辑更清晰
  • 有助于了解axios的内部运作机制
  • 解决回调函数地狱问题(通过链式调用 then 返回一个新的Promise对象

基本使用

/*使用promise管理异步任务*/
const p = new Promise((resolve, reject) => {
	setTimeout(function () {
		//resolve() => fulfilled状态-已兑现 => then()
		// resolve('成功')
		//reject() => rejected状态-已兑现 => catch()
		reject(new Error('失败'))
	}, 2000)
})

console.log(p)

p.then(result => {
	console.log(result)
}).catch(error => {
	console.log(error)
})

PromiseAll

/*当我们需要执行几个Promise对象,同时获取他们的结果时,使用Promise静态方法Promise.all([])*/
const ps = Promise.all([new Promise(resolve => resolve(1)), new Promise(resolve => resolve(2))])
// 这里的result是一个数组
ps.then(result => console.log(result))
const p1 = new Promise(resolve => resolve(3))
const p2 = new Promise(resolve => resolve(4))
const p3 = new Promise((resolve, reject) => {
	reject('错误1')
})
const p4 = new Promise((resolve, reject) => {
	reject('错误2')
})
// 当执行的过程中发生错误是,会中断执行并抛出第一个错误
Promise.all([p1, p2, p3, p4]).then(result => {
	console.log(result)
}).catch(error => {
	console.log(error)
})

Promise 配合 XMLHttpRequest使用

<script type="text/javascript">
	
	const p = new Promise((resolve, reject) => {
		const xhr = new XMLHttpRequest()
		xhr.open('get', 'http://hmajax.itheima.net/api/city?pname=湖南省')
		xhr.addEventListener('loadend', function (result) {
			if (result.target.status === 200) {
				resolve(JSON.parse(xhr.response))
			} else {
				reject(new Error(xhr.response))
			}
		})
		xhr.send()
	})
	
	console.log(p)
	
	p.then(result => {
		console.log('执行成功', result)
	}).catch(error => {
		//错误对象要是用console.dir详细打印
		console.dir('执行错误', error)
	})
</script>

XMLHttpRequest 配合 Promise进行简单封装和使用

// 封装为一个函数 MyAxios,返回的是一个Promise对象
function MyAxios({method = 'get', url, params, data}) {
    //返回一个Promise对象
    return new Promise((resolve, reject) => {
        /*1. 实例化一个xhr对象*/
        const xhr = new XMLHttpRequest()
        /*判断是否有传参,有传参拼接在URL后面*/
        url = params ? url + function () {
            const keys = Object.keys(params)
            const values = Object.values(params)
            return '?' + keys.map((item, index) => item + '=' + values[index]).join('&')
        }() : url
        // console.log(url)
        xhr.open(method, url)
        // 有请求体,给请求头设置请求体文本类型
        xhr.setRequestHeader('Content-Type', 'application/json')
        /* 添加load事件,获取响应结果 */
        xhr.addEventListener('loadend', function () {
            /*200-300之间的状态码为响应成功状态码*/
            if (xhr.status >= 200 && xhr.status < 300) {
                /*返回的内容类型为JSON字符串,对它进行解析并返回*/
                resolve(JSON.parse(xhr.response))
            } else {
                reject(new Error(xhr.response))
            }
        })
        /*判断是否为post请求*/
        data ? xhr.send(JSON.stringify(data)) : xhr.send()
    })
}

/*get请求 传参*/
/*new MyAxios({
    method: 'get',
    url: 'http://hmajax.itheima.net/api/area',
    params: {
        pname: '河北省',
        cname: '石家庄市'
    }
}).then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
})*/

/*post请求*/
/*new MyAxios({
    method: 'post',
    url: 'http://hmajax.itheima.net/api/register',
    data: {username: 'itheima095', password:' 123456'}
}).then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
})*/

/*获取城市天气*/
/*new MyAxios({
    method: 'get',
    url: 'http://hmajax.itheima.net/api/weather',
    params: {
        city: '110100'
    }
}).then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
})*/

/*获取天气案例*/
document.querySelector('.search-city').addEventListener('input', debounce(fun, 500))
const ul = document.querySelector(`ul`)
function fun(e) {
    console.log('发送请求', e.target.value)
    new MyAxios({
        url: 'http://hmajax.itheima.net/api/weather/city',
        params: {
            city: e.target.value
        }
    }).then(result => {
        console.log(result)
        ul.innerHTML = result.data.map(item => `<li data-code="${item.code}">${item.name}</li>`).join('')
    }).catch(error => {
        console.log(error)
    })
}
ul.addEventListener('click', function (e) {
    const li = e.target
    if (li.tagName === 'LI') {
        console.log(li.dataset.code);
        new MyAxios({
            method: 'get',
            url: 'http://hmajax.itheima.net/api/weather',
            params: {
                city: li.dataset.code
            }
        }).then(result => {
            console.log(result)
        }).catch(error => {
            console.log(error)
        })
    }
})
//防抖函数
function debounce(fun, delay = 500) {
    let timer = null
    return function (e) {
        if (timer)
            clearTimeout(timer)
        timer = setTimeout(function () {
            fun(e)
            timer = null
        }, delay)
    }
}

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

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

相关文章

接口自动化测试系列-yml管理测试用例

项目源码 目录结构及项目介绍 整体目录结构&#xff0c;目录说明参考 测试用例结构类似httprunner写法&#xff0c;可参考demo 主要核心函数 用例读取转换json import yaml import main import os def yaml_r():curpath f{main.BASE_DIR}/quality_management_logic/ops_ne…

centos7挂载nfs存储

centos7挂载nfs存储 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.安装NFS服务 #安装nfs yum -y install rpcbind nfs-utils#创建目录&#xff08;我这边是/data/upload&#xff09; mkdir -p /data/upload#写/etc/fstab文件&#xff0c;添加要挂载的nfs盘 172.16.…

Ubuntu18.04系统下通过ROS控制Kinova真实机械臂-多种实现方式

所用测试工作空间test_ws&#xff1a;包含官网最原始的功能包 一、使用Kinova官方Development center控制真实机械臂 0.在ubuntu系统安装Kinova机械臂的Development center&#xff0c;这一步自行安装&#xff0c;很简单。 1.使用USB连接机械臂和电脑 2.Development center…

【力扣周赛】第 361 场周赛(⭐前缀和+哈希表 树上倍增、LCA⭐)

文章目录 竞赛链接Q1&#xff1a;7020. 统计对称整数的数目竞赛时代码——枚举预处理 Q2&#xff1a;8040. 生成特殊数字的最少操作&#xff08;倒序遍历、贪心&#xff09;竞赛时代码——检查0、00、25、50、75 Q3&#xff1a;2845. 统计趣味子数组的数目竞赛时代码——前缀和…

jQuery成功之路——jQuery动画效果和遍历效果概述

一、jQuery动画效果 1.1显示效果 方法 方法名称解释show([speed],[easing],[fn]])显示元素方法hide([speed],[easing],[fn]])隐藏元素方法toggle([speed],[easing],[fn])切换元素方法&#xff0c;显示的使之隐藏&#xff0c;隐藏的使之显示 参数 参数名称解释speed三种预…

CocosCreator3.8研究笔记(五)CocosCreator 脚本说明及使用(下)

在Cocos Creator中&#xff0c;脚本代码文件分为模块和插件两种方式&#xff1a; 模块一般就是项目的脚本&#xff0c;包含项目中创建的代码、引擎模块、第三方模块。 插件脚本&#xff0c;是指从 Cocos Creator 属性检查器中导入的插件&#xff0c;一般是引入第三方引入库文件…

管理类联考——数学——汇总篇——知识点突破——数据分析——排列组合

角度——&#x1f434; 角度——&#x1f469; 排列组合的基本步骤&#xff08;固定解题体系&#xff09; 先取后排&#xff1a;即先取出元素&#xff0c;后排列元素&#xff0c;切勿边取边排. 逐次进行&#xff1a;按照一定的顺序逐次进行排列组合. 实验结束&#xff1a;整个…

vscode保存格式化自动去掉分号、逗号、双引号

之前每次写完代码都是双引号还有分号&#xff0c;看着很难受&#xff0c;就像修改一下&#xff0c;让它变成单引号&#xff0c;并且不加上引号&#xff1a;如下形式&#xff0c;看着简洁清晰明了 修改方式&#xff1a;更改 settings.json 文件 快捷键“Ctrl Shift P”打开命令…

UmeTrack: Unified multi-view end-to-end hand tracking for VR 复现踩坑记录

在 github 上找到了开源代码&#xff1a;https://github.com/facebookresearch/UmeTrack/tree/main 环境配置 运行第三行&#xff0c;报错&#xff0c;缺少torch。改成先运行第四行&#xff0c;成功。 再运行第三行&#xff0c;报错&#xff0c;required to install pyproj…

uniapp 集成蓝牙打印功能(个人测试佳博打印机)

uniapp 集成蓝牙打印功能&#xff08;个人测试京博打印机&#xff09; uniapp 集成蓝牙打印功能集成佳博内置的接口 uniapp 集成蓝牙打印功能 大家好今天分析的是uniapp 集成蓝牙打印功能&#xff0c;个人开发是app,应该是支持H5(没试过) 集成佳博内置的接口 下载dome地址&…

空间复杂度和时间复杂度

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;时间复杂度、空间复杂度、算法☀️每日 一言&#xff1a;车到山前必有路&#xff0c;船到码头自然直&#xff01; 一、前言 时间复杂度和空间复杂度是算法和数据结构领域中两个重要的概念&#…

服务器(I/O)之多路转接

五种IO模型 1、阻塞等待&#xff1a;在内核将数据准备好之前&#xff0c;系统调用会一直等待。所有的套接字&#xff0c;默认都是阻塞方式。 2、非阻塞等待&#xff1a;如果内核没有将数据准备好&#xff0c;系统调用仍然会返回&#xff0c;并且会返回EWUOLDBLOCK或者EAGAIN错…

springboot邮件发送和接收验证码

springboot邮件篇 要在Internet上提供电子邮件功能&#xff0c;必须有专门的电子邮件服务器。例如现在Internet很多提供邮件服务的厂商&#xff1a;新浪、搜狐、163、QQ邮箱等&#xff0c;他们都有自己的邮件服务器。这些服务器类似于现实生活中的邮局&#xff0c;它主要负责接…

【C语言】辗转相除法求最大公约数(详解)

辗转相除法求最大公约数 辗转相除法&#xff08;又称欧几里德算法&#xff09;是一种用于求解两个整数的最大公约数的方法。本文将使用C语言来实现辗转相除法&#xff0c;并对其原理进行解释。 辗转相除法的原理 辗转相除法的原理非常简单。假设有两个整数a和b&#xff0c;其…

Vue+Element-ui+SpringBoot搭建后端汽车租赁管理系统

最近在做项目&#xff0c;花了一周的时间搭建了一个十分完备的汽车租赁后端管理系统。页面采用纯Vue2Element-ui搭建&#xff0c;后端采用SpringbootMybatis搭建&#xff0c;数据库采用Mysql。包括了登录验证&#xff0c;根据不同权限进入不同界面、数据增删改查、表格分页、表…

iOS实时监控与报警器

在现代信息化社会中&#xff0c;即使我们不在电脑前面也能随时获取到最新的数据。而苹果公司提供的iOS推送通知功能为我们带来了一种全新的方式——通过手机接收实时监控和报警信息。 首先让我们了解一下iOS推送通知。它是一个强大且灵活可定制化程度高、适用于各类应用场景&a…

(二十一)大数据实战——Flume数据采集之复制和多路复用案例实战

前言 本节内容我们完成Flume数据采集的一个多路复用案例&#xff0c;使用三台服务器&#xff0c;一台服务器负责采集本地日志数据&#xff0c;通过使用Replicating ChannelSelector选择器&#xff0c;将采集到的数据分发到另外俩台服务器&#xff0c;一台服务器将数据存储到hd…

vue3 封装千分位分隔符自定义指令

toLocaleString作用&#xff1a;在没有指定区域的基本使用时&#xff0c;返回使用默认的语言环境和默认选项格式化的字符串。可点击进入MDN查看 // 千分位分隔符指令 import { Directive, DirectiveBinding } from vueconst thousandSeparator: Directive {mounted(el: any, …

window系统 bat脚本开启和关闭防火墙

前言 手动去关闭和开启防火墙太麻烦 命令 开始防火墙 netsh advfirewall set allprofiles state on关闭防火墙 netsh advfirewall set allprofiles state off

拦截器和异常处理器

拦截器和异常处理器 拦截器 拦截器(Interceptor)&#xff0c;主要完成请求参数的解析、将页面表单参数赋给值栈中相应属性、执行功能检验、程序异常调试等工作。 准备 创建模块 如下为完整的项目结构 web.xml <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee&qu…