# AJAX
## 优缺点
优点:
* 最大的一点是页面无刷新,页面与服务器通信效果很好
* 使用异步操作。不会打断用户操作。有更加迅速的反应能力。
缺点:
* 浏览器不兼容,IE和人类浏览器可能会有不兼容的情况出现
## 关于ajax与单线程机制
我们知道js是一个单线程机制的语言。在浏览器中,主要有一下四种线程:
* GUI渲染线程
* js引擎线程
* 浏览器事件触发线程
* HTTP请求线程
他们是如何产生交互的呢? 通常线程的交互以事件的方式发生,通过回调的方式予以通知。事件回调又通过**先进先出**的方式存入**任务队列**的末尾。等到js引擎空闲时,任务队列中的任务就会排队被执行,这些回调一般有 setTimeout, setInterval, click, ajax异步请求等回调。
> 浏览器中, js引擎线程会循环从 任务队列 中读取事件并且执行, 这种运行机制称作 Event Loop (事件循环).
在ajax请求中,我们从新建一个XMLHttprequest 到open send方法的调用,都是一个同步执行的方法。在send方法内部开始,浏览器就会为网络请求发起HTTP请求线程,同时js引擎线程继续向下执行。在收到response时,触发HTTP线程的回调事件。**onreadystatechange**这个回调事件就像我们上面说的一样,没有被立即执行,反而放置到了**任务队列**中等到js引擎闲置之后,才开始依次触发。
在onreadystatechange中,很可能是有dom操作的,这时,js引擎线程会被挂起,转而执行GUI渲染线程,触发回流或重绘。js引擎再次运行时,GUI线程又被挂起等到js闲置时可能会执行。
> 除了 GUI渲染线程 和 js引擎线程 是互斥的. 其他线程相互之间, 都是可以并行执行的
## readyState 只读属性
readyState记录了ajax调用中的所有可能状态。
一共有0-4五种可能取值。
* 0:未初始化 请求已经建立,但是未开始初始化,未调用open方法
* 1:初始化 请求已经建立,但未发送。已经调用open,但未调用send。
* 2:发送数据 请求已发送,send已经调用,已经收到响应头。
* 3:数据传送中 请求处理中,因响应内容不全, 这时通过responseBody和responseText获取可能会出现错误。
* 4:完成 数据接收完毕,此时可以通过responseBody与responseText获取完整响应数据。
## onreadystatechange
此回调方法在readyState状态改变时触发,在一个收到响应的ajax请求周期中,这个方法会触发四次。所以可以在里面绑定一些操作。
~~~
xhr.onreadystatechange = function(e){
if(xhr.readystate==4){
var s = xhr.status;
if((s >= 200 && s < 300) || s == 304){
var resp = xhr.responseText;
//TODO ...
}
}
}
~~~
## status 只读
表示http请求状态的状态码,默认初始为0,如果服务器没有显式的制定时,默认为200。
## ajax的原生实现
~~~
function ajax(options) {
var url = options.url || '';
var type = options.type.toUpperCase() || 'GET';
var data = options.data || '';
var success = options.success || function () {};
var error = options.error || function () {};
var dataArr = [];
if(!url) return;
// 格式化参数
if (typeof data === 'object') {
for (var key in data) {
if (data.hasOwnProperty(key)) {
dataArr.push(key + '=' + data[key]);
}
}
} else {
dataArr = data.split('&');
}
// 生成XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 设置监听方法
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
success(xhr.responseText, xhr);
} else {
error(xhr.statusText);
}
}
}
// 判断请求方法
if (type === 'GET') {
url = url + '?' + dataArr.join('&');
xhr.open(type, url.replace(/\?$/g, ''), true);
xhr.send();
} else if (type === 'POST') {
xhr.open(type, url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(dataArr.join('&'));
}
}
ajax({
url: 'http://localhost:8000',
type: 'get',
data: 'name=sky&age=24',
success: function (res) {
console.log(res);
},
error: function (err) {
console.log(err);
}
});
~~~
## Ajax同步异步问题
一.什么是同步请求:(false)
同步请求即是当前发出请求后,浏览器什么都不能做,必须得等到请求完成返回数据之后,才会执行后续的代码,相当于是排队,前一个人办理完自己的事务,下一个人才能接着办。也就是说,当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,页面处于一个假死状态,当这个AJAX执行完毕后才会继续运行其他代码页面解除假死状态(即当ajax返回数据后,才执行后面的function)。
二.什么是异步请求:(true)
异步请求就当发出请求的同时,浏览器可以继续做任何事,Ajax发送请求并不会影响页面的加载与用户的操作,相当于是在两条线上,各走各的,互不影响。
> 一般默认值为true,异步。异步请求可以完全不影响用户的体验效果,无论请求的时间长或者短,用户都在专心的操作页面的其他内容,并不会有等待的感觉。
>
**关于两者不同:**
1. 异步:在异步模式下,当我们使用AJAX发送完请求后,可能还有代码需要执行。这个时候可能由于种种原因导致服务器还没有响应我们的请求,但是因为我们采用了异步执行方式,所有包含AJAX请求代码的函数中的剩余代码将继续执行。如果我们是将请求结果交由另外一个JS函数去处理的,那么,这个时候就好比两条线程同时执行一样。
2. 同步:在同步模式下,当我们使用AJAX发送完请求后,后续还有代码需要执行,我们同样将服务器响应交由另一个JS函数去处理,但是这时的代码执行情况是:在服务器没有响应或者处理响应结果的JS函数还没有处理完成return时,包含请求代码的函数的剩余代码是不能够执行的。就好比单线程一样,请求发出后就进入阻塞状态,直到解除阻塞,余下的代码才会继续执行。
- html
- 冒泡/捕获/委托
- 前端路由
- Dom
- 创建节点API
- 页面修改型API
- 节点查询型API
- 节点关系型API
- 元素属性API
- DOM事件
- classList
- 性能优化
- 节流防抖
- localStorage sessionStorage
- BOM
- meta
- data属性
- js实现拖拽
- html5
- 关于meta
- 轮播图
- js实现拖放
- 电话号inputFormater
- js
- es6
- promise
- iterator
- generator
- async
- proxy
- Set
- Map
- Object的扩展
- String
- Iterator
- Symbol
- 解构赋值
- 函数式编程
- module
- 基本数据类型
- 数组相关codings
- for of/for in
- this
- call bind apply
- 闭包
- 作用域
- prototype与继承
- 深浅拷贝
- setTimeOut/setInterval
- 垃圾处理机制
- 设计模式
- 观察者模式
- 单例模式
- 策略模式
- RegExp
- with
- 其他玩意
- Error/Stack Trace
- 面向对象
- css
- 回流重绘
- %取值
- 属性继承/属性优先级
- flex
- BFC
- 盒模型
- 设置css的方法
- 定位机制
- 块级/行内元素
- hack和一些别的玩意
- css动画
- 几个布局
- 画图形
- css3
- animation对比transform
- 点击不同图片区域跳转不同
- css选择器性能问题
- vh rem em
- css选择器
- 伪类伪元素
- css匹配原理
- 数据结构与算法
- 数据结构
- 树
- 链表
- 栈和队列
- 排序
- 归并排序
- 插入排序
- 选择排序
- 冒泡排序
- 快速排序
- 递归
- 回溯法
- 搜索算法
- 动态规划
- http
- 跨域问题
- CORS
- GET/POST
- ajax
- ajax上传文件
- http缓存
- https
- TCP/UDP
- cookie/session
- http2.0
- spdy
- websocket
- React
- redux
- 生命周期
- 虚拟dom与diff
- 双向数据绑定
- mvvm
- setState
- contextApi props reudx
- 高阶组件
- react-redux
- Fiber
- react-router
- 受控/非受控组件
- 待整理
- webpack
- loader实现
- 前端安全
- 移动端适配
- Vue
- 传值
- 其他