同步与异步?
- 同步:后一个任务等待前一个任务执行完毕后再执行
- 异步:非阻塞的,主逻辑与异步逻辑相互独立,主逻辑不需要等待异步逻辑完成,而是可以立即执行下去
事件循环?
- JS中用来存储待执行回调函数的队列包含2个不同特定的列队
- 宏任务队列:用来保存待执行的宏任务(回调)比如:定时器回调/DOM事件回调/ajax回调;
- 微任务队列:用来保存待执行的微任务(回调)比如:promise回调/MutationObserver回调/process.nextTick;
- 事件循环?执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环。
异步编程的实现方式?
- 回调函数:多个回调函数嵌套的时候会造成回调函数地狱,上下两层的回调函数间的代码耦合度太高,不利于代码的可维护
Promise的方式:使用 Promise 的方式可以将嵌套的回调函数作为链式调用。但是使用这种方法,有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确。generator的方式:在 generator 内部对于异步操作的方式,可以以同步的顺序来书写,yield表达式可以暂停函数执行,next方法用于恢复函数执行,这使得Generator函数非常适合将异步任务同步化async函数:可以将异步逻辑,转化为同步的顺序来书写,并且这个函数可以自动执行。本质是generator和promise实现的一个自动执行的语法糖,它内部自带执行器。
Promise 对象?
- 是异步编程的一种解决方法,它是一个构造函数,由它的实例对象来封装一个异步操作,并且可以获取其成功或失败的结果。
- 构造函数
Promise内部自动执行一个执行器函数,执行器函数接收两个参数resolve、reject两个回调函数,executor执行器函数是同步回调函数。 - 有三个状态:
pending、fulfilled、rejected。实例的状态只能由pending变fulfilled或者pending变rejected状态,并且状态一经改变,就没办法再被改变了。 - 状态如何改变的呢?通过
resolve()函数将状态改为fulfilled;reject()函数将状态改为rejected。 - 解决回调地狱:回调函数嵌套使用,不利于阅读以及异常处理。Promise的链式调用解决了回调地狱。它实例对象具有
then和catch方法,而它们的返回结果依然是一个Promise对象,因此可以使用.符号进行链式调用。
//创建一个新的promise
let p = new Promise((resolve,reject)=>{
// 成功后调用resolve(),这时promise状态由pending变为fulfilled,返回一个新的Promise
// 成功后调用reject(),这时promise状态由pending变为rejected, 返回一个新的Promise
})
p.then(
(value)=>{}, //接收到成功的value数据
(reason)=>{} //接收到失败的reason数据
)
async/await?
async函数,这个函数就是纯同步执行,不过返回值为promise对象await表达式:① 返回值如果表达式是promise对象,await返回的是promise成功的值;如果表达式是其它值,直接将此值作为await的返回值。- await此行代码之后的语句一起作为整体变为微队列中的异步回调。相当于给后面的代码套了一层 then 方法。
- 如果await的promise失败了,就会抛出异常,需要通过 try..catch 捕获处理
- 真正起作用的是await,可以把async关键字简单的当作一个 标识符. 因为如果异步函数中不使用 await关键字,除了返回值为promise对象,其执行基本上跟普通函数没有什么区别。
XHR请求
- 全称是
XMLHttprequest,用于与服务器进行交互,通过它可以在不刷新页面的情况下请求特定的url,获取数据。所以可以在不影响用户操作的情况下,更新页面的局部内容。 - 语法
a.
XMLHttpRequest(): 创建XHR对象的构造函数
b.open(): 初始化一个请求, 参数为: (method, url[, async])
c.send(data): 发送请求 abort(): 中断请求
d.setRequestHeader(name, value): 设置请求头
e.onreadystatechange(): 绑定readyState改变的监听。0初始 1open()之后 2send()之后 3请求中 4请求完成
// 1 手写ajax
// 1. 创建XHR实例,let xhr = new XMLHttpRequest()
// 2. 配置请求:xhr.open('GET', url)
// 3. 发去请求: xhr.send()
// 4. 获取请求状态 onreadystatechange() = function(){ xhr.readyState xhr.status xhr.responseText}
let ajax = function(url){
return new Promise((resolve, reject)=>{
//创建XHR对象的实例
let xhr = new XMLHttpRequest()
// 初始化请求
xhr.open('GET', url, true)
//设置请求头
xhr.setRequestHeader('Content-Type', 'application/json')
// 绑定回调函数:onreadystatechange(),监听readyState的改变
xhr.onreadystatechange = function(){
//readyState:4请求完成后再判断状态码status
if(xhr.readystate !== 4) return;
if(xhr.status >= 200 || xhr.status < 300){
//请求成功调用resolve(responseData)
resolve(xhr.responseText)
}else{
// 请求失败调用reject()
reject(new Error(xhr.responseText))
}
}
//发送请求
xhr.send()
})
}
// 2 fetch请求
fetch(url).then( response => {
return response.json()
}).then(data=>{
// 请求成功,处理响应数据
console.log("成功获取数据:", data);
}).catch(error=>{
// 请求失败,处理响应数据
console.error("获取数据失败:", data);
})
axios
- 是什么?前端最流行的ajax请求库,它的特点是:①基于promise封装的ajax请求库;②支持请求\响应拦截器;③支持取消请求;④浏览器和node端都能使用,浏览器端发起
XMLHttpRequests请求,node 端发起http请求; - 基本使用:①基本语法
axios({config});②快捷方法axios.get(url, { params, ...config })等
// 1 基本语法
axios({
method:'get', url:'/api/user', params:{id: 1}, timeout:5000
}).then(response=>{
console.log('请求成功:', response.data);
}).catch(error=>{
console.error('请求失败:', error);
})
// 2 快捷方法
// i. get获取数据,请求指定的信息,返回实体对象
// ii post:向指定资源提交数据(例如表单提交或文件上传)
// ⅲ. put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
// ⅳ. patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
// ⅴ. delete:请求服务器删除指定的数据
// ⅵ. head:获取报文首部
axios.get(url, { params, ...config })//get参数通过params配置(自动拼接到URL的查询字符串)
axios.post(url, data, { ...config }) //post参数通过data传参 有请求体
axios.put(url, data, { ...config })
axios.delete(url, { params, ...config })
ajax、axios、fetch 的区别
- AJAX 即
AsynchronousJavascriptAndXML(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。它可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
缺点:①基于原生 XHR 开发,XHR 本身的架构不清晰;②配置和调用方式非常混乱,而且基于事件的异步模型不友好。
- Fetch是ES6
基于标准 Promise实现的,支持async/await,代码结构比起 ajax 简单多。脱离了XHR,不是 ajax 的进一步封装,没有使用 XMLHttpRequest 对象。
缺点:①fetch 默认不会带 cookie,需要添加配置项:
fetch(url, {credentials: 'include'});②fetch 不支持 abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费;③fetch 没有办法原生监测请求的进度,而 XHR 可以
- Axios 是一种基于
Promise 封装的 HTTP 客户端库,其核心是对浏览器端XMLHttpRequest(XHR)和 Node.js 端http 模块的现代化封装
特点:①基于promise封装的ajax请求库;②支持请求\响应拦截器;③支持取消请求;④浏览器和node端都能使用