Ajax + Promise复习简单小结simple

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} = resultconsole.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} = resultconsole.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.targetif (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 = nullreturn function (e) {if (timer)clearTimeout(timer)timer = setTimeout(function () {fun(e)timer = null}, delay)}
}

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

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

相关文章

C语言学习系列-->字符函数和字符串函数

文章目录 一、字符函数1、字符分类函数2、字符转换函数 二、字符串函数1、strlen概述模拟实现 2、strcpy概述模拟实现 3、strcat概述模拟实现 3、strcmp概述模拟实现 4、有限制的字符串函数strncpystrncatstrncmp 4、strstr概述模拟实现 一、字符函数 1、字符分类函数 包含头…

vue3:22、vue-router的使用

import { createRouter, createWebHistory } from vue-router//history模式&#xff1a;createWebHistory //hash模式&#xff1a;createWebHashHistory//vite中的环境变量 import.meta.env.BASE_URL 就是vite.config.js中的base配置项 const router createRouter({history:…

Spring Data JPA:简化数据库交互的艺术

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

lv3 嵌入式开发-11 Linux下GDB调试工具

目录 1 GDB简介 2 GDB基本命令 3 GDB调试程序 1 GDB简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说&#xff0c;GDB主要帮助你完成下面四个方面的功能&#xff1a; 1、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#…

【leetcode 力扣刷题】回文串相关题目(KMP、动态规划)

回文串相关题目 5. 最长回文子串动态规划中心扩展算法 214. 最短回文串336. 回文对 5. 最长回文子串 题目链接&#xff1a;5. 最长回文子串 题目内容&#xff1a; 题目就是要我们找s中的回文子串&#xff0c;还要是最长的。其实想想&#xff0c;暴力求解也行……就是遍历所有的…

Python编程的八大魔法库

Python是一门广受欢迎的编程语言&#xff0c;其生态系统丰富多彩&#xff0c;拥有许多令人惊叹的依赖库&#xff0c;可以帮助程序员们在各种领域中创造出令人瞠目结舌的应用。在这篇文章中&#xff0c;我们将探讨Python编程的十大神奇依赖库&#xff0c;它们像魔法一样&#xf…

jmeter 计数器Counter

计数器可以用于生成动态的数值或字符串&#xff0c;以模拟不同的用户或数据。 计数器通常与用户线程组结合使用&#xff0c;以生成不同的变量值并在测试中应用。以下是计数器的几个常用属性&#xff1a; 变量前缀&#xff08;Variable Name Prefix&#xff09;&#xff1a;定义…

G. The Morning Star

Problem - G - Codeforces 思路&#xff1a;想了挺长时间的&#xff0c;一直没想到一个简便的方法在瞎搞。我们发现对于某个点来说&#xff0c;其他的点如果能够跟他匹配&#xff0c;那么一定在这8个方向上&#xff0c;而同时这8个方向其实对应这4条直线&#xff0c;假设点为(x…

静态路由 网络实验

静态路由 网络实验 拓扑图初步配置R1 ip 配置R2 ip 配置R3 ip 配置查看当前的路由表信息查看路由表信息配置静态路由测试 拓扑图 需求&#xff1a;实现 ip 192.168.1.1 到 192.168.2.1 的通信。 初步配置 R1 ip 配置 system-view sysname R1 undo info-center enable # 忽略…

C语言经典100例题(55)--从一个整数a中把从右端开始的4-7位取出来

目录 题目 问题分析 右移操作符 左移操作符 方法一 方法二 运行结果 题目 用c语言从一个整数a中把从右端开始的4-7位取出来 问题分析 右移操作符 右移操作符是一种位运算符&#xff0c;用于将二进制数向右移动指定的位数。它通常用符号" >> "表示…

W11下CMake MinGW配置OpenCV和Qt

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 前几天将cuda版本的opencv给编译成功了&#xff0c;当时用的VS的MSVC&…

day37 线程

一、线程安全 二、多线程并发的安全问题 当多个线程并发操作同一临界资源 由于线程切换实际不确定 导致操作顺序出现混乱 产生的程序bug 严重时出现系统瘫痪 临界资源 &#xff1a;操作该资源的完整流程同一时间只能被单一线程操作的资源 多线程并发会出现的各种问题、 如…

聊聊 HTMX 吧

写在前面 最近看了几篇关于 htmx 的文章&#xff0c;自己也去看了一眼官网&#xff0c;也去油管看了一下当时 htmx 发布会的时候他们的演示&#xff0c;下面说几点我对这个所谓的新型起来的技术的看法&#xff0c; 他的来源是什么 首先说一下他虽然是一个新型的技术&#xff0c…

Java 多线程系列Ⅶ(线程安全集合类)

线程安全集合类 前言一、多线程使用线性表二、多线程使用栈和队列三、多线程下使用哈希表 前言 在数据结构中&#xff0c;我们学习过 Java 的内置集合&#xff0c;但是我们知道&#xff0c;我们学过的大多数集合类都是线程不安全的&#xff0c;少数如 Vector&#xff0c;Stack…

小程序分销机制介绍,小程序二级分销功能有哪些?

为什么有越来越多的用户选择使用小程序&#xff1f;跟“高大上”的APP相比&#xff0c;小程序不仅可以减少下载安装的复杂流程&#xff0c;还具备操作便捷、沉淀私域数据的优势。蚓链分销小程序具备裂变二维码、实时分佣、分销身份升级、层级分佣、商品个性化佣金设定等功能&am…

TortoiseSVN 详细操作指南

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 热爱技术的小郑 1、引言 考虑以下几种情况&#xff1a; 你是否在一个…

golang面试题:json包变量不加tag会怎么样?

问题 json包里使用的时候&#xff0c;结构体里的变量不加tag能不能正常转成json里的字段&#xff1f; 怎么答 如果变量首字母小写&#xff0c;则为private。无论如何不能转&#xff0c;因为取不到反射信息。如果变量首字母大写&#xff0c;则为public。 不加tag&#xff0c…

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解 文章目录 【Spring Cloud系统】- 轻量级高可用工具Keepalive详解一、概述二、Keepalive分类2.1 TCP的keepalive2.2 HTTP的keep-alive2.3 TCP的 KeepAlive 和 HTTP的 Keep-Alive区别 三、nginx的keepalive配置3.1 nginx保持…

连接云-边-端,构建火山引擎边缘云网技术体系

近日&#xff0c;火山引擎边缘云网络产品研发负责人韩伟在LiveVideoStack Con 2023上海站围绕边缘云海量分布式节点和上百T的网络规模&#xff0c;结合边缘云快速发展期间遇到的各种问题和挑战&#xff0c;分享了火山引擎边缘云网的全球基础设施&#xff0c;融合开放的云网技术…

数据结构——七大排序[源码+动图+性能测试]

本章代码gitee仓库&#xff1a;排序 文章目录 &#x1f383;0. 思维导图&#x1f9e8;1. 插入排序✨1.1 直接插入排序✨1.2 希尔排序 &#x1f38a;2. 选择排序&#x1f38b;2.1 直接选择排序&#x1f38b;2.2 堆排序 &#x1f38f;3. 交换排序&#x1f390;3.1 冒泡排序&#…