引言
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。 这是因为 JavaScript 这门脚本语言诞生的任务所致——JavaScript 是为处置惩罚页面中用户的交互,以及操纵 DOM而诞生的。好比我们对某个DOM 元素进行添加和删除操纵,不能同时进行。 应该先辈行添加,之后再删除。 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如许所导致的题目是: 假如 JS 执行的时间过长,如许就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉
为了解决这个题目,利用多核 CPU 的盘算本领,HTML5 提出 Web Worker 标准,允许JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。 同步,前一个任务结束后再执行后一个任务,程序的执行次序与任务的排列次序是同等的、同步的。好比做饭的同 步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。 异步你在做一件事情时,因为这件事情会耗费很长时间,在做这件事的同时,你还可以去处置惩罚其他事情。好比做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。 他们的本质区别:这条流水线上各个流程的执行次序不同。
同步任务:同步任务都在主线程上执行,形成一个执行栈。
异步任务:JS 的异步是通过回调函数实现的。 一般而言,异步任务有以下类型::
1、平常事件,如 click、resize 等
2、资源加载,如 load、error 等
3、定时器,包罗 setInterval、setTimeout 等 异步任务相关添加到任务队列中
4、AJAX
事件循环(event loop)
概念:
JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码,网络和处置惩罚事件以及执行队列中的子任务。
缘故原由:
JavaScript是单线程(某一刻只执行一行代码),为了让耗期间码不阻塞其他代码运行,计划了事件循环模型。
执行机制:
JS执行代码的逻辑是次序读取的,但是可以或许分辨出同步任务的代码和异步任务的代码。
一般来说,当读取到同步任务代码时候会将代码带进执行栈,直接执行;
当JS读取到异步任务的代码(如setTimeout,setInterval,各种平常事件,资源加载等)时,会将这个任务放进浏览器中处置惩罚,浏览器处置惩罚完毕后(如setTimeout执行完毕,或完成了点击事件等),会将内里的回调函数放入任务队列中,当所有执行栈中的代码执行完毕时候,再将任务队列中的回调函数放入执行栈中执行。不同的是,JS中的Promise对象本身是同步的任务,但当它调用then和catch方法时,会将方法内的回调函数放入另一个任务队列中,因此这里产生了两个任务队列,我们经常把前者称为宏任务队列,后者称为微任务队列。当所有执行栈中的代码执行完毕后,JS引擎会先将微任务队列的回调函数放入执行栈中执行完毕后再将宏任务队列中的回调函数放入执行栈中执行。
- console.log(1)
- setTimeout(() => {
- console.log(2)
- }, 0)
- const p = new Promise((resolve, reject) => {
- resolve(3)
- })
- p.then(res => {
- console.log(res)
- })
- console.log(4)
复制代码 如该代码中,打印数字先后次序是1、4、3、2
JS在执行中,次序读取,先打印1;之后遇到定时器,将它交给浏览器处置惩罚,浏览器在0ms后将回调函数放进了宏任务队列;之后读到Promise,当它调用then函数时候将then内里的回调函数放入微任务队列中;再读取到打印4;执行栈清空,之后JS引擎先将微任务队列的回调放入执行栈中执行了,打印3;最后将宏任务队列中的回调函数放进执行栈执行,打印2。
AJAX
定义:
AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。简单地说,就是利用XMLHTTPRequest对象与服务器通讯。它可以利用JSON、XML、HTML、text文本等格式发送和接收数据。AJAX最吸引人的就是它的异步特性,也就是说它可以在不重新革新页面的情况下与服务器通讯,交换数据或更新页面
概念:
AJAX 是浏览器与服务器进行数据通讯的技术。
基本利用:
- //获取button元素
- const btn = document.querySelector('button')
- const result = document.querySelector('#result')
- //绑定事件
- btn.addEventListener('click',function(){
- //创建对象
- const xhr = new XMLHttpRequest()
- //初始化 设置请求方法和url xhr.open('请求方法','请求地址')
- xhr.open('GET','http://127.0.0.1:8000/server')
- //发送
- xhr.send()
- //事件绑定 处理服务端返回的结果
- //on 当什么的时候 readystate是xhr对象中的属性,是状态表示
- // 有 0 1 2 3 4 一共5个值
- // 0表示未初始化,最开始属性的值就是0,
- // 1表示open方法调用完毕
- // 2表示send方法调用完毕
- // 3表示服务端返回了部分结果
- // 4表示服务端返回了所有结果
- // change 改变
- // 这5个值一共改变4次,改一次触发一次事件
- xhr.onreadystatechange = function(){
- //判断 服务端是否返回所有结果
- if(xhr.readyState === 4){
- //判断响应状态码 200 404 403 401 500
- //2xx都表示成功
- if(xhr.status >= 200 && xhr.status<300){
- //处理结果 行 头 空行 体
- // 1.响应行
- console.log(xhr.status) //状态码
- console.log(xhr.statusText)//状态字符串
- console.log(xhr.getAllResponseHeaders())//所有响应头
- console.log(xhr.response)//响应体
- result.innerHTML = xhr.response
- }
- }
- }
- })
复制代码 1.创建XMLHTTPRequest对象并定义xhr作为常量接收
2.初始化:调用open方法设置哀求方法和url,此中open方法还可以或许设置第三个参数,true(异步) 或false(同步),默认为true
3.调用send方法发送
4.监听onreadystatechang事件,执行回调,当readystate为4同时状态码在200到300之间时候对服务端返回的数据(主要是响应体xhr.response)执行要做的事情
此中,初始化中调用open方法设置哀求方法主要有GET(获取数据)和POST(提交数据)等
此中若哀求方法为GET,可以在url网址中携带查询参数,语法是
http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2
而利用POST方法则可以在send方法中设置参数,格式一般为JSON字符串,作为哀求体,提交上去。
回调地狱(Callback Hell)
在AJAX的原生实现中,利用了onreadystatechange事件,当该事件触发并且符合一定条件时,才能拿到想要的数据,之后才能开始处置惩罚数据,如许做看上去并没有什么麻烦,但假如这个时候,我们还需要别的一个AJAX哀求,这个新AJAX哀求的此中一个参数,得从上一个AJAX哀求中获取,这个时候我们就不得不等待上一个接口哀求完成之后,再哀求后一个接口。
-
- const xhr = new XMLHttpRequest();
- xhr.open('get', 'https://xx.com/api?a=2&b=3');
- xhr.send();
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status >= 200 && xhr.status < 300) {
- console.log(xhr.responseText)
- //伪代码....
- const xhr = new XMLHttpRequest();
- xhr.open('get','http://www.xx.com?a'+xhr.responseText);
- xhr.send();
- xhr.onreadystatechange = function(){
- if(xhr.readyState === 4){
- if(xhr.status>=200 && xhr.status<300){
- console.log(xhr.responseText)
- }
- }
- }
- }
- }
- }
-
复制代码 当出现第三个AJAX(乃至更多)仍然依赖上一个哀求时,我们的代码就变成了一场灾难。
这场灾难,往往也被称为回调地狱。
Promise
定义:
Promise对象用于体现一个异步操纵的终极完成(或失败)及其结果值。
利益:
1. 逻辑更清晰
2. 了解 axios 函数内部运作机制
3. 能解决回调函数地狱题目
基本利用:
- const p = new Promise((resolve,reject)=>{
- const xhr = new XMLHttpRequest()
- xhr.open('GET','http://xx/api/province123')
- xhr.send()
- xhr.onreadystatechange = ()=>{
- if(xhr.readyState === 4){
- if(xhr.status>=200&&xhr.status<300){
- console.log(xhr.response)
- resolve(xhr.response)
- }else{
- reject(new Error(xhr.response))
- }
- }
- }
- }).then(result=>{
- document.querySelector('.my-p').innerHTML = JSON.parse(result).list.join('<br>')
- }).catch(error=>{
- console.dir(error)
- document.querySelector('.my-p').innerHTML = error.message
- })
复制代码 1.创建Promise对象,内部传入以resolve函数和reject函数为参数的函数,定义常量p接收
2.内部执行例如AJAX的哀求,将乐成返回的哀求体作为参数传入resovle函数,调用resovle后会调用then函数,此时promise的状态由pending变为fullfilled;将没有乐成返回的哀求体作为参数传入reject函数,调用reject后则执行catch函数,prmise状态由pending变为rejected;此中最后可以调用finally函数,最后一定调用
以上为Promise的基本用法,今后基于Promise对象,ES7提出了async和await作为解决异步的终极方案。
async和await
异步函数 async function 中可以利用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中停息,直到其运行结束再继承运行。
异步函数实际上原理与 Promise 原生 API 的机制是一模一样的,只不过更便于程序员阅读。
基本利用:
- // 1. 定义async修饰函数
- async function getData() {
- // 2. await等待Promise对象成功的结果
- const pObj = await axios({url: 'http://xxx/api/province'})
- const pname = pObj.data.list[0]
- const cObj = await axios({url: 'http://xxx/api/city', params: { pname }})
- const cname = cObj.data.list[0]
- const aObj = await axios({url: 'http://xxx/api/area', params: { pname, cname }})
- const areaName = aObj.data.list[0]
- document.querySelector('.province').innerHTML = pname
- document.querySelector('.city').innerHTML = cname
- document.querySelector('.area').innerHTML = areaName
复制代码 axios
概念:
Axios 是一个基于Promise 网络哀求库,作用于node.js 和浏览器中。 在服务端它利用原生 node.js http 模块, 而在客户端 (浏览端) 则利用 XMLHttpRequests。
特性:
- 从浏览器创建XMLHttpRequest
- 支持 Promise API
- 拦截哀求和响应
- 转换哀求和响应数据
- 取消哀求
- 超时处置惩罚
- 查询参数序列化支持嵌套项处置惩罚
- 自动将哀求体序列化为:
- JSON (application/json)
- Multipart / FormData (multipart/form-data)
- URL encoded form (application/x-www-form-urlencoded)
- 将 HTML Form 转换成 JSON 进行哀求
- 自动转换JSON数据
基本利用:
- btn.onclick = ()=>{
- axios({
- //请求方法
- method:'POST',
- //url
- url:'/axios-server',
- //url查询参数
- params:{
- vip:10,
- level:30
- },
- //头信息
- headers:{
- a:100,
- b:200
- },
- //请求体参数
- data:{
- username:'admin',
- password:'admin'
- }
- }).then(response=>{
- console.log(response)
- //响应状态码
- console.log(response.status)
- //响应状态字符串
- console.log(response.statusText)
- //响应头信息
- console.log(response.headers)
- //响应体
- console.log(response.data)
- })
- }
复制代码 以对象形式,传入各种配置项的参数,将返回的结果作为then的参数接收并处置惩罚。
由于篇幅关系,就只能将基本的AJAX、Promise、axios概念和用法介绍到这,更详细的用法待日后学习。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |