update: ajax异步任务

This commit is contained in:
qianguyihao 2021-05-27 12:54:01 +08:00
parent 07102a7261
commit 48a1ab234f
2 changed files with 157 additions and 87 deletions

View File

@ -22,31 +22,41 @@ JavaScript 语言和执行环境是**单线程**。即同一时间,只能处
- 异步任务不进入主线程而是进入**任务队列**Event Queue的任务只有"任务队列"通知主线程某个异步任务可以执行了该任务才会进入主线程执行
代码举例
```js
console.log('同步任务');
console.log('同步任务1');
setTimeout(() => {
console.log('异步任务');
}, 1000);
console.log('同步任务2');
```
比如上面的代码里第一行代码是同步任务**立即执行**定时器里的回调函数是异步任务需要等 1 秒后才会执行
打印结果是
比如说网络图片的请求就是一个异步任务前端如果同时请求多张网络网络图片谁先请求完成就让谁先显示出来
```
同步任务1
同步任务2
异步任务
```
假如网络图片的请求做成同步任务那就会出大问题所有图片都得排队加载如果第一张图片未加载完成就得卡在那里造成阻塞导致其他图片都加载不出来页面看上去也会很卡顿这肯定是不能接受的
代码解释第一行代码是同步任务**立即执行**定时器里的回调函数是异步任务需要等 1 秒后才会执行假如定时器里的代码是同步任务那需要等待1秒后才能执行最后一行代码`console.log('同步任务2')`也就是造成了主线程里的同步任务阻塞这不是我们希望看到的
比如说网络图片的请求就是一个异步任务前端如果同时请求多张网络网络图片谁先请求完成就让谁先显示出来假如网络图片的请求做成同步任务那就会出大问题所有图片都得排队加载如果第一张图片未加载完成就得卡在那里造成阻塞导致其他图片都加载不出来页面看上去也会很卡顿这肯定是不能接受的
### 前端使用异步的场景
什么时候需要**等待**就什么时候用异步
什么时候需要**等待**就什么时候用异步常见的异步场景如下
- 定时器setTimeout定时炸弹setInterval循环执行
- 1定时器setTimeout定时炸弹setInterval循环执行
- 事件绑定比如说按钮绑定点击事件之后用户爱点不点我们不可能卡在按钮那里什么都不做所以应该用异步
- 2事件绑定比如说按钮绑定点击事件之后用户爱点不点我们不可能卡在按钮那里什么都不做所以应该用异步
- 网络请求含接口请求ajax 请求网络图片加载
- 3网络请求含接口请求ajax 请求网络图片加载
- ES6 中的 Promise
- 4ES6 中的 Promise
现在的大部分软件项目都是前后端分离的后端生成接口前端请求接口前端发送 ajax 请求向后端请求数据然后**等待一段时间**才能拿到数据这个请求过程就是异步任务
@ -61,11 +71,6 @@ js 中常见的接口调用方式,有以下几种:
下一篇文章我们重点讲一下接口调用里的 Ajax然后在 ES6 语法中学习 **Promise**在这之前我们需要先了解同步任务异步任务的事件循环机制
### 多次异步调用的顺序
- 多次异步调用的结果顺序可能不同步
- 异步调用的结果如果**存在依赖**则需要通过回调函数进行嵌套
### 事件循环机制重要
@ -80,6 +85,13 @@ js 中常见的接口调用方式,有以下几种:
- 当主线程的任务执行完毕之后此时主线程处于空闲状态于是会去读取 Event Queue 中的任务队列如果有任务则进入到主线程去执行
### 多次异步调用的顺序
- 多次异步调用的结果顺序可能不同步
- 异步调用的结果如果**存在依赖**则需要通过回调函数进行嵌套
## 定时器代码示例
掌握了上面的事件循环原理之后我们来看几个例子
@ -162,7 +174,8 @@ setTimeout(() => {
上面的案例中异步任务需要等待 1004 毫秒之后才会从 Event Table 进入到 Event Queue这在面试中也经常被问到
## 异步任务举例
### 例1加载图片
### 1加载图片
```js
// 加载图片的异步任务
@ -193,8 +206,31 @@ loadImage(
);
```
### 2定时器计时移动 DOM 元素
### 例2定时器计时
```js
// 函数封装:定义一个定时器,每间隔 delay 毫秒之后,执行 callback 函数
function myInterval(callback, delay = 100) {
let timeId = setInterval(() => callback(timeId), delay);
}
myInterval((timeId) => {
// 每间隔 500毫秒之后向右移动 .box 元素
const myBox = document.getElementsByClassName('box')[0];
const left = parseInt(window.getComputedStyle(myBox).left);
myBox.style.left = left + 20 + 'px';
if (left > 300) {
clearInterval(timeId);
// 每间隔 10 毫秒之后,将 .box 元素的宽度逐渐缩小,直到消失
myInterval((timeId2) => {
const width = parseInt(window.getComputedStyle(myBox).width);
myBox.style.width = width - 1 + 'px';
if (width <= 0) clearInterval(timeId2);
}, 10);
}
}, 200);
```

View File

@ -58,6 +58,76 @@ AjaxAsynchronous Javascript And XML异步 JavaScript 和 XML。它并
5服务端响应获取返回的数据
## XMLHttpRequest 对象详解
我们在上一段讲解了使用 XMLHttpRequest 对象的五个步骤本段我们讲一下注意事项
### 发送请求
发送请求的方法
```javascript
open(method, url, async);
```
参数解释
- method请求的类型GET POST
- url文件在服务器上的位置
- asynctrue异步 false同步
另外还有个方法仅用于 POST 请求
```javascript
send(string);
```
### POST 请求时注意
如果想让 form 表单提交数据那样使用 POST 请求就需要使用 XMLHttpRequest 对象的 setRequestHeader()方法 来添加 HTTP 然后在 send() 方法中添加想要发送的数据
```javascript
xmlhttp.open('POST', 'ajax_test.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send('name=smyhvae&age=27');
```
### onreadystatechange 事件
注册 onreadystatechange 事件后每当 readyState 属性改变时就会调用 onreadystatechange 函数
readyState存有 XMLHttpRequest 的状态 0 4 发生变化
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成且响应已就绪
status
- 200: "OK"
- 404: 未找到页面
onreadystatechange 事件中** readyState 等于 4且状态码为 200 表示响应已就绪**
### 服务器响应的内容
- responseText获得字符串形式的响应数据
- responseXML获得 XML 形式的响应数据
如果响应的是普通字符串就使用 responseText如果响应的是 XML使用 responseXML
## 手写 Ajax
### 手写第一个 Ajax 请求
@ -223,76 +293,30 @@ myAjax('a.json', (res) => {
![](http://img.smyhvae.com/20180228_1605.gif)
### Ajax 多个接口的嵌套请求重要
## XMLHttpRequest 对象详解
我们在做异步任务的时候经常会涉及到多个接口的嵌套请求比如说接口 1 请求完成后需要根据接口 1 的数据请求接口 2接口 2 请求完成后需要根据接口 3 的数据请求接口 3以此类推
我们在上一段讲解了使用 XMLHttpRequest 对象的五个步骤本段我们讲一下注意事项
需求描述
### 发送请求
- 请求接口 1根据用户名获取用户 id
发送请求的方法
- 请求接口 2根据用户 id 获取用户的年龄性别等信息
```javascript
open(method, url, async);
代码实现思路
```js
myAjax('http://localhost:8888/php/user.php?name=千古', (userInfo) => {
// 根据第一个接口返回的 userInfo.id继续请求第二个接口
myAjax(`http://localhost:8888/php/houdunren.php?id=${userInfo['id']}`, (res) => {
console.log(response);
});
});
```
参数解释
我们在实战开发中经常会涉及到接口请求之间的**依赖**需要上一个接口请求返回的数据来发送本次请求这种场景经常遇到需要记住
- method请求的类型GET POST
- url文件在服务器上的位置
- asynctrue异步 false同步
另外还有个方法仅用于 POST 请求
```javascript
send(string);
```
### POST 请求时注意
如果想让 form 表单提交数据那样使用 POST 请求就需要使用 XMLHttpRequest 对象的 setRequestHeader()方法 来添加 HTTP 然后在 send() 方法中添加想要发送的数据
```javascript
xmlhttp.open('POST', 'ajax_test.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send('name=smyhvae&age=27');
```
### onreadystatechange 事件
注册 onreadystatechange 事件后每当 readyState 属性改变时就会调用 onreadystatechange 函数
readyState存有 XMLHttpRequest 的状态 0 4 发生变化
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成且响应已就绪
status
- 200: "OK"
- 404: 未找到页面
onreadystatechange 事件中** readyState 等于 4且状态码为 200 表示响应已就绪**
### 服务器响应的内容
- responseText获得字符串形式的响应数据
- responseXML获得 XML 形式的响应数据
如果响应的是普通字符串就使用 responseText如果响应的是 XML使用 responseXML
但这种层层嵌套的代码会导致**回调地域**的问题也不利于维护我们在后续的 ES6 章节中会讲解 Promise它是一种更优雅的异步任务解决方案
## jQuery 中的 Ajax
@ -302,14 +326,18 @@ JQuery 作为最受欢迎的 js 框架之一,常见的 Ajax 已经帮助我们
```javascript
$.ajax({
url: '01.php', //请求地址
data: 'name=fox&age=18', //发送的数据
url: 'https://xxx.com/getUserInfo.php', // 接口的请求地址
data: 'name=fox&age=18', // 请求参数
type: 'GET', //请求的方式
success: function (argument) {}, // 请求成功执行的方法
success: function (argument) {
// 接口请求成功时调用
console.log('接口请求成功');
},
beforeSend: function (argument) {}, // 在发送请求之前调用,可以做一些验证之类的处理
error: function (argument) {
console.log(argument);
}, //请求失败调用
// 接口请求失败时调用
console.log('接口请求失败');
},
});
```
@ -332,15 +360,17 @@ $.ajax({
$(function () {
$('#btn').click(function () {
$.ajax({
url: 'data.php',
url: 'https://xxx.com/getUserInfo.php', // 接口的请求地址
dataType: 'text',
data: 'name=fox&age=18', // 请求参数
type: 'get',
success: function (data) {
console.log('接口请求成功');
alert(data);
//$("#showInfo").html(data);
// $("#showInfo").html(data);
},
error: function (e) {
console.log(e);
error: function (err) {
console.log('接口请求失败:' + err);
},
});
});
@ -370,3 +400,7 @@ echo $text;
扫一扫你将发现另一个全新的世界而这将是一场美丽的意外
![](https://img.smyhvae.com/20200102.png)
```
```