AJAX 全解

207 阅读11分钟

发送网络请求

标题内容备注特点
AJAXJS 发请求和收响应
是一个技术统称,概念模型
特征是让页面实现局部刷新
浏览器提供XMLHttpRequest构造函数,可构造出xhr对象,JS 通过xhr实现部分刷新页面存在跨域问题
若请求内部还有请求嵌套,就会有回调地狱问题
Promise对异步操作的封装可通过独立的接口添加在异步操作执行成功、失败时执行的方法不可以取消请求
Fetch API由Fetch标准定义,提供了一个获取资源的接口
Fetch的核心是对 HTTP 接口的抽象
使用.then链式调用 处理结果
不使用回调函数 而用 Promise 比XMLHttpRequest的实现更简洁
fetch 可自定义是否携带Cookie
不支持JSONP
async / await写异步代码的新方式
优于回调函数和Promise
不需要写.then,不需要写匿名函数处理Promise的resolve值,也不需要定义多余的data变量
axios基于promise封装的网络请求库
提供两个http请求适配器XHR和HTTP:
XHR的核心是浏览器端的XMLHttpRequest对象
HTTP的核心是node的http.request方法
CancelToken取消请求

AJAX

AJAX 直译为异步(Async) JSXML ,是一种技术总结,是浏览器上的功能:

浏览器提供一套用于实现网络编程的 API ,可通过JS调用,从而实现用 JS 发请求和收响应。

image.png

异步的从服务器轻量级的获取新数据,在不重新加载整个页面的情况下,刷新页面。

JS 发网络请求到成功得到响应 这个过程的持续时间:几百毫秒至1-2s之间。

缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(用同源策略解决)
  • SEO 搜索引擎优化不友好

应用场景

  • 百度搜索关键字,显示的联想列表:
image.png
  • 京东左侧栏,商品分类,浮动显示内容:
image.png

核心

浏览器可以发请求,收响应,是因为浏览器在window上加了一个XMLHttpRequest全局函数,用它可以构造出一个xhr对象,JS 通过操控xhr实现部分刷新页面。

xhr 的属性和方法内容
send方法send(请求体)
open方法open(请求方法, URL, 是否异步请求)
readystate属性用来对应服务器状态码
记录请求响应时候处于哪个过程
readystate属性值的变化会触发readystatechange事件
readyState的值的变化,就是一个请求的生命周期:
0 表示未调用open()方法
1 表示调用了open()方法,但未调用send()方法
2 表示已调用send()方法,还没收到响应
3 表示开始下载,已经接收到部分数据
4 表示已经接收到全部数据,可以把响应的内容显示在页面了

用 AJAX 加载 CSS

以前是用<link>标签加载 CSS,也可以用 AJAX 加载 CSS:

// index.html
<!DOCTYPE html>
<html>
  <head>
  <title>ajax</title>
  </head>
  <body>
    <h1>AJAX demo 2</h1>
    <p>
      <button id="getCSS">请求 CSS</button>
    </p>
    <script src="/main.js"></script>
   </body>
</html>
// main.js
getCSS.onclick = () => {
  const request = new XMLHttpRequest();
  request.open('GET','/style.css');
  // `onload`比较局限,后来替换为`onreadystatechange`事件
  request.onload = () => {
    // 创建 style 标签
    const style = document.createElement('style')
    // 填写 style 内容
    style.innerHTML = request.response
    // 插到 head 里面
    document.head.appendChild(style)
  };
  request.onerror = () => {
    console.log('fail')
  }
  request.send()
}

用 AJAX 加载 JS

以前是用<script src="2.js"></script>标签加载 JS,也可以用 AJAX 加载 JS:

console.log('我是2.js')
// index.html
<!DOCTYPE html>
<html>
  <head>
  <title>ajax</title>
  </head>
  <body>
    <h1>AJAX demo 2</h1>
    <p>
      <button id="getCSS">请求 CSS</button>
      <button id="getJS">请求 JS</button>
    </p>
    <script src="/main.js"></script>
   </body>
</html>
// main.js
getJS.onclick = () => {
  const request = new XMLHttpRequest();
  request.open('GET','/2.js');
  // `onload`比较局限,后来替换为`onreadystatechange`事件
  request.onload = () => {
    // 创建 script 标签
    const script = document.createElement('script')
    // 填写 script 内容
    script.innerHTML = request.response
    // 插到 head 里面
    document.head.appendChild(script)
  };
  request.onerror = () => {
    console.log('fail')
  }
  request.send()
}

用 AJAX 加载 HTML

以前不会加载 HTML,

// 3.html
<div style="background:red; width:300px height:300px;">
  动态内容
<div>
// index.html
<!DOCTYPE html>
<html>
  <head>
  <title>ajax</title>
  </head>
  <body>
    <h1>AJAX demo 2</h1>
    <p>
      <button id="getCSS">请求 CSS</button>
      <button id="getJS">请求 JS</button>
      <button id="getHTML">请求 HTML</button>
    </p>
    <script src="/main.js"></script>
   </body>
</html>
// main.js
getHTML.onclick = () => {
  const request = new XMLHttpRequest();
  request.open('GET','/3.html');
  request.onload = () => {
    // 创建 div 标签
    const div = document.createElement('div')
    // 填写 div 内容
    div.innerHTML = request.response
    // 插到 body 里面
    document.body.appendChild(div)
  };
  request.onerror = () => {
    console.log('fail')
  }
  request.send()
}

替换onloadonreadystatechange

// main.js
getCSS.onclick = () => {
  const request = new XMLHttpRequest();
  request.open('GET','/style.css');
  request.onreadystatechange = () => {
    // 下载完成,但不知道是成功 2xx 还是失败 4xx 5xx
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        const style = document.createElement('style')
        // 填写 style 内容
        style.innerHTML = request.response
        // 插到 head 里面
        document.head.appendChild(style)
      }else{
        alert('加载 CSS 失败')
      }
    }      
  };
  request.send()
}

小结

// 发送请求的流程:
// 1. 创建一个请求代理对象 xhr
let xhr = new XMLHttpRequest();
// 2. 通过代理对象建立与服务端的连接
xhr.open('GET', 'http://xxx', 是否异步请求)   
// 3. 基于连接发送请求
xhr.send()

// 接收响应的流程:
// 4. 等待服务端的响应 目前没有这种等待的说法
// 5. 接收到服务端的响应结果 响应报文中的响应体
xhr.onreadystatechange = function(){
// 请求状态发生变化时触发
}
  • 由于 JS单线程,AJAX 并没有设计一个阻塞的方法,接收响应的方式是通过事件触发方式
  • onreadystatechange并不是专门设计的响应事件,只要是请求状态变了就触发
  • xhr.responseText为获取响应报文的响应体

用 AJAX 加载 JSON

JSON 标记语言

用来展示数据,类似 HTML、Markdown;作者是道格拉斯;

支持的数据类型有:string(只支持双引号)、number、bool、null(没有undefined)、object、array

不支持的数据类型:函数和变量(不支持引用

类型转换:

  • JSON.parse 把符合JSON语法的字符串转换成 JS 对应类型的数据
  • JSON.stringify 是 JSON.parse 的逆运算

实例

// 5.json
{
  "name":"frank",
  "age":"18",
  "xxx":null  
}
// index.html
<!DOCTYPE html>
<html>
  <head>
  <title>ajax</title>
  </head>
  <body>
    <h1>AJAX Hello <span id="myName"></span></h1>
    <p>
      <button id="getJSON">请求 JSON</button>
    </p>
    <script src="/main.js"></script>
   </body>
</html>
// main.js
getJSON.onclick = () => {
  const request = new XMLHttpRequest();
  request.open('GET','/5.json');
  request.onreadystatechange = () => {
    // 下载完成,但不知道是成功 2xx 还是失败 4xx 5xx
    if(request.readyState === 4){
      if(request.status >= 200 && request.status < 300){
        const object = JSON.parse(request.response)
        myName.textContent = object.name
      }
    }      
  };
  request.send()
}

image.png

这也是一种用户登录后,显示用户名的方法。

用 AJAX 加载 分页

// db/page1.json
[
  {"id":1},
  {"id":2},
  {"id":3},
  {"id":4},
  {"id":5},
  {"id":6},
  {"id":7},
  {"id":8},
  {"id":9},
  {"id":10}
]

(待更新)

Fetch

ES6新特性 (XHR的替代品)

Fetch本质上是一种标准,该标准定义了请求、响应和绑定的流程。 Fetch标准还定义了Fetch() API,其提供了一个获取资源的接口(包括跨域),它类似于 XMLHttpRequestFetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body等。

fetch()方法

用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。

let wtf = fetch('https://dog.ceo/api/breeds/image/random');
console.log(wtf);  // Promise{}

fetch(url, options).then(function(response){
  // 处理 HTTP 响应
  }, function(error){
  // 处理 网络错误
})
fetch() 参数内容备注
第一个参数urlGET方法
第二个参数
(可选参数)
{method, body, header, cookie}POST方法

HTTP GET方法

fetch返回一个Promise,Promise对象有三个属性:原型、状态和结果。可以用Promise的方法来操作服务器响应的内容。

Promise对象内容
原型catch()、then()方法、json方法
状态fulfilled 成功执行
结果body、headers、status、url属性
fetch('https://dog.ceo/api/breeds/image/random')
    // 用 then 指明请求成功我们需要执行什么动作
    // then 里面传入的函数用来操控服务器响应的内容
    // Promise对象的原型中有 json 方法,用于把服务器拿回来的数据处理为JS能操作的数据
    .then( response => console.log(response.json()) )

fetch就是一个基于Promise语法的函数,Promise.then以后会返回一个Promise, fetch.then也返回一个Promise,可以利用Promise的链式来处理:

fetch('https://dog.ceo/api/breeds/image/random')
    .then( response => console.log(response.json()) );
    .then( data => console.log(data) );
    // 输出结果为一个对象,这个对象的message属性里面有图片的url地址

实现每次点击按钮的时候,都会调用fetch函数:把图片地址添加到img标签的src属性里,把fetch内容放在事件监听函数内,并把最后获取到的对象的message属性赋值给图片的src属性。

<button>点击获取单身狗的照片</button>
<img>
<script>
const button = document.querySelector('button');
const img = document.querySelector('img');
button.addEventListener('click', ()=>{
fetch('https://dog.ceo/api/breeds/image/random')
    .then( response => response.json() );
    .then( data => img.src = data.message );
})
</script>

HTTP POST方法

<button>点击获取单身狗的照片</button>
<input type="text" placeholder="请输入单身狗姓名">
<script>
const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', ()=>{
fetch('https://jsonplaceholder.typicode.com/users',{
    method:'POST',
    body: JSON.stringify({name:input.value}),
    header:{
        '"Content-Type":"application/json'
    },
})
    .then( response => response.json() );
    .then( data => console.log(data) );
});
</script>

异步与回调

异步任务需要在得到结果时通知 JS 来拿结果。怎么通知?让 JS 留一个函数地址给浏览器,等异步任务完成时浏览器调用该函数地址,同时把结果作为参数传给该函数,这个函数是写给浏览器调用的,所以是回调函数。

区别:异步任务需要用到回调函数来通知结果,但回调函数不一定只用在异步任务里,回调可以用到同步任务里,array.forEach(n => console.log(n))这是同步回调。

如何识别异步函数

异步操作会将相关回调添加到任务队列中。而不同的异步操作添加到任务队列的时机也不同,如AddEventListenersetTimeout,AJAX 处理的方式都不同,这些异步操作是由浏览器内核的webcore来执行的:

webcore的3种API内容备注
DOM Binding处理DOM绑定事件onclick事件触发时,回调函数会立即被webcore添加到任务队列中
Network处理Ajax请求在网络请求返回时,才会将对应的回调函数添加到任务队列中
timer对计时器进行延时处理当时间到达的时候,才会将回调函数添加到任务队列中

如果一个函数的返回值处于以下三个东西内部,那么这个函数就是异步的:

  • setTimeout
  • AJAX(即 XMLHttpRequest)
  • AddEventListener

异步举例

请求 JSON 时,request.send()之后,并不能直接得到response,这是因为 JS 发网络请求到成功得到响应的大概时间段是几百毫秒到2秒钟之间,就是必须等到readyState变为4后,浏览器回头(将来)调用request.onreadystatechange函数,才能得到request.response,这跟餐厅给你发送微信提醒的过程是类似的。

异步任务有两个结果

  • 方法一:回调接受两个参数
fs.readFile('./1.txt', (error, data)=>{
  if(error){console.log('失败'); return}
  console.log(data.toString())  // 成功
})
  • 方法二:用两个回调
ajax('get', '/1.json', data=>{}, error=>{})
// 前面函数是成功回调,后面函数是失败回调

ajax('get', '/1.json',{
  success:()=>{}, fail:()=>{}
})
// 接受一个对象,对象有两个 key 表示成功和失败

Promise

定义

Promise是前端解决异步编程的统一方案(ES6规范),最大的缺点是不可以取消请求axios可以用CancelToken取消请求。

异步编程主要有:

// fs文件操作
require('fs').readFile('./index.html', (err, data)=>{})

// ajax网络请求
$.get('/server', (data)=>{})

// 定时器
setTimeout(()=>{}, 1000);

为什么要用 Promise

  1. 支持链式调用,可解决回调地狱问题;

  2. 指定回调函数的方式更加灵活:启动异步任务 => 返回promise对象 => 给 promise 对象绑定回调函数(可在异步任务结束后指定)

Promise 的状态

状态是实例对象中的一个属性PromiseState,状态只能改变一次,由pendingresolvedrejected,无论变为成功或失败,都会有一个结果数据。

属性值内容
pending未决定的(默认值)
resolved / fullfilled成功
rejected失败
// 改变 Promise 对象状态的方式
let p = new Promise((resolve, reject)=>{
  // 1. resolve 函数 由 pending 改为 resolved(fulfilled)
  resolve('ok');
  // 2. reject 函数 由 pending 改为 rejected
  reject('error');
  // 3. 抛出错误
  throw 'error';
})

Promise 对象的值

对象的值是实例对象中的另一个属性PromiseResult,保存着对象成功或失败的结果,以下两个函数可以修改PromiseResult属性的值:resolvereject

Promise 的 API

  1. Promise 构造函数
Promise(excutor){}
// excutor函数为同步调用
excutor = (resolve, reject) => {}
  1. Promise.prototype.then 方法

Promise实例必须实现then这个方法,用于指定成功或失败的回调函数,返回一个新的 promise 对象。必须可以接收两个函数作为参数

(onResolved, onRejected) => {}
  1. Promise.prototype.catch 方法
  2. Promise.all 方法

只有所有promise都成功才成功,只要有一个失败了就直接失败

// promises : 包含 n 个 promise 的数组
(promises)=>{} 

let p1 = new Promise((resolve, reject)=>{
  resolve('OK');
})
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('oh,Yeah');
const result = Promise.all([p1, p2, p3]);
console.log(result);

image.png

// promises : 包含 n 个 promise 的数组
(promises)=>{} 

let p1 = new Promise((resolve, reject)=>{
  resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('oh,Yeah');
const result = Promise.all([p1, p2, p3]);
console.log(result);

image.png

  1. Promise.race 方法

第一个完成的 promise 的结果状态就是最终的结果状态:

let p1 = new Promise((resolve, reject)=>{
  resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('oh,Yeah');
const result = Promise.race([p1, p2, p3]);
console.log(result);

image.png

举个栗子 定时器:

// v1.0
<div class="container">
  <h2>Promise</h2>
  <button id="btn">点击抽奖</button>
</div>
function rand(m, n){
  return Math.ceil(Math.random()*(n-m+1))+m-1;
}
// 点击按钮 2s后显示是否中奖 
// 获取元素对象
const btn = document.querySelector('#btn');
// 绑定单击事件
btn.addEventListener('click', function(){  
  setTimeout(()=>{
    let n = rand(1,100);
    if(n <= 30){alert('恭喜中奖')}
    else{alert('再接再厉')}
  }, 2000)
})
// v2.0 Promise 形式实现
<div class="container">
  <h2>Promise</h2>
  <button id="btn">点击抽奖</button>
</div>
// 构造函数接收一个函数类型的参数, 此函数还有两个函数类型的形参
const p = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    let n = rand(1,100);
    if(n <= 30){
      resolve();  // 将 p 的状态设置为成功
    }else{
      reject();   // 将 p 的状态设置为失败
    }
  }, 2000);
});
function rand(m, n){
  return Math.ceil(Math.random()*(n-m+1))+m-1;
}
// 调用 then 方法 指定成功或失败时的回调
// 接收两个函数类型的形参
// 第一(二)个函数是 p 的状态成功(失败)时的回调
p.then(()=>{
  alert('恭喜中奖')
}, ()=>{
  alert('再接再厉')
})

举个栗子 AJAX 请求:

// v1.0 ajax实现
<div class="container">
  <h2>Promise 封装 AJAX 操作</h2>
  <button id="btn">点击发送 AJAX</button>
</div>
<script>
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(){  
  // 1. 创建对象
  const xhr = XMLHttpRequest();
  // 2. 初始化
  xhr.open('GET', 'https://api.xx');  // 第2个参数是api接口地址
  // 3. 发送请求
  xhr.send();
  // 4. 处理响应结果
  xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
      if(xhr.status >= 200 && xhr.status < 300){
        console.log(xhr.response);
      }else{
        console.log(xhr.status);
      }
    }
  }
});
</script>
// v2.0 promise
<div class="container">
  <h2>Promise 封装 AJAX 操作</h2>
  <button id="btn">点击发送 AJAX</button>
</div>
<script>
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(){
  // 创建 Promise
  const p = new Promise((resolve, reject)=>{
    // 1. 创建对象
    const xhr = XMLHttpRequest();
    // 2. 初始化
    xhr.open('GET', 'https://api.xx');  // 第2个参数是api接口地址
    // 3. 发送请求
    xhr.send();
    // 4. 处理响应结果
    xhr.onreadystatechange = function(){
      if(xhr.readyState === 4){
        if(xhr.status >= 200 && xhr.status < 300){
          resolve(xhr.response);
        }else{
          reject(xhr.status);
        }
      }
    }
  });
  p.then(value=>{
    console.log(value);
  }, reason=>{
    console.log(reason);
  })
});
</script>
// v3.0 promise 封装 ajax
<script>
// 封装 sendAJAX函数 发送 GET AJAX 请求
function sendAJAX(){
  return new Promise((resolve, reject)=>{
    const xhr = XMLHttpRequest();
    xhr.open('GET', url);
    xhr.send();
    xhr.onreadystatechange = function(){
      if(xhr.readyState === 4){
        if(xhr.status >= 200 && xhr.status < 300){
          resolve(xhr.response);
        }else{
          reject(xhr.status);
        }
      }
    }
  });
}
</script>

---
sendAJAX('https://api.xx')  // api接口地址
.then(value => {
  console.log(value);
}, reason => {
  console.log(reason);
})

现实生活中的 Promise 模型和概念

一对男女朋友,女人承诺new Promise)在2.14情人节的时候给男人送一个孩子作为情人节礼物,承诺会产生两种结果,成功怀孕(resolve)解决承诺,反之就是不成功(reject)拒绝承诺,不管成功与否,两人还是会在2.14情人节后结婚领证,也就是说成功与否这件事不是马上就知道结果的,需要一段时间才知道,以上就是Promise的基本形式,即回调的升级版,在处理一些花费比较长时间的任务时,使用Promise就可以进行异步的处理,防止阻塞。

情人节过后,实际只有女人知道结果,男人不得而知,女人心计一下,成功的话就称呼男人为孩子他爹,失败的话,她还称呼男人为老公,即可以为两种结果找到合适的理由(为resolvereject里面传入参数,可以在后面使用)。揭晓结果时,如果成功,女人就会用then来表示,如果失败,女人就会用catch来表示,女人就会抱着男人不放,但最终还是结婚了,用finally来表示。

代码还原刚才的栗子

const isPregnant = true;
const promise = new Promise( (resolve, reject)=>{
    if(isPregnant){
        resolve(`孩子他爹`)
    } else {
        reject(`老公`)
    }
} );

promise
    .then( name=>{
        console.log(`男人成为了${name}`);
    })
    .catch( name=>{
        console.log(`男人成为了${name}!`);
    })
    .finally(()=>{
        console.log(`男人和女人最终结婚了`);
    })
    
// 输出结果为 ture时,男人成为了孩子他爹 男人和女人最终结婚了
// 输出结果为 false时,男人成为了老公 男人和女人最终结婚了

async / await

async 函数

函数的返回值为 promise 对象,其结果由 async 函数执行的返回值决定。与 then 方法的返回结果一致。

async 函数中可以没有 await,反之 await 必须在 async 函数中。

async function main(){
  // 1. 返回值为 非 Promise 类型的数据
  return 521;   // 见 截图 1
  // 2. 返回值为 Promise 对象
  return new Promise((resolve, reject)=>{
    resolve('OK');    // 见 截图 2
    reject('Error');  // 见 截图 3
  })
  // 3. 抛出异常
  throw 'error'  // 见 截图 4
}
let result = main();
console.log(result);

image.pngimage.pngimage.pngimage.png

await 表达式

await 右侧的表达式一般为 promise 对象(返回的是 promise 成功的值),也可以是其他的值(此值作为 await 的返回值)。

async function main(){
  let p = new Promise((resolve, reject)=>{
    resolve('OK');
    // 情况3 reject('Error')
  })
  // 1. 右侧为 promise 
  let res = await p;
  console.log(res);  // 输出 OK
  // 2. 右侧为 其他类型的数据
  let res2 = await 20;
  console.log(res2); // 输出 20
  // 3. 如果 promise 是失败的状态
  try{
    let res3 = await p;
  }catch(e){
    console.log(e);   // 输出 Error
  }     
}

async 与 await 结合发送 AJAX请求

<button id="btn">点击获取段子</button>
// 可用 axios 封装这个函数
function sendAJAX(url){
  return new Promise((resolve, reject)=>{})
}
const btn = document.querySelector('#btn');
btn.addEventListener('click', async function(){
  let duanzi = await sendAJAX('https://api.xxx');
  console.log(duanzi);
})

axios

axios 是一个基于 promise 封装的网络请求库,它是基于 XHR 进行二次封装。

axios 是随着 Vue 的兴起而被广泛使用的,目前来说,绝大多数的 Vue 项目中的网络请求都是利用 Axios 发起的。当然它并不是一个思想,或者一个原生 API,它是一个封装库。

JSON Server 搭建 HTTP 服务

创建 full fake REST API

// 1. install
npm install -g json-server

// 2. Create a db.json file with some data

// 3. Start JSON Server
json-server --watch db.json

axios 是什么

Promise based HTTP client for the browser and node.js

axios 能干什么

  • 发送 AJAX 请求(浏览器端)
  • 发送 HTTP 请求(node.js端)
  • 支持 Promise API
  • 请求、响应拦截器(本质是函数。请求之前做准备工作,响应的结果预处理)
  • 转换请求、响应的数据
  • 取消请求
  • 自动转换为JSON数据

安装 axios

npm install axios
yarn add axios
// cdn 引入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

axios 基本使用

<button>发送GET请求</button>

const btns = document.querySelectorAll('button');
btns[0].onclick = function(){
  axios({
    method: 'GET',
    url: '/user/12345',
  }).then(response =>{
    console.log(response)
  })
}
<button>发送POST请求</button>

const btns = document.querySelectorAll('button');
btns[1].onclick = function(){
  axios({
    method: 'POST',
    url: '/user/12345',
    // 设置 请求体
    data:{
      title:"绝世好文",
      author:"张三"
    }
  }).then(response =>{
    console.log(response)
  })
}

axios 其他方式发送请求

axios.request({
  methods:'GET',
  url:'https://xxx'
}).then(response =>{
  console.log(response)
})

// 发送 POST 请求
axios.post(
  'https://xxx',
  {
    "body":"hello",
    "postId":2
  }
).then(response =>{
  console.log(response)
})

axios 响应结果

标题内容
configmethod 请求类型
url 请求地址
请求体
data
响应体的结果
axios自动将服务器返回结果JSON解析为对象
headers
响应头信息
request
原生 AJAX 请求对象

相关概念

标题内容备注
并发代表计算机能够同时执行多项任务单核处理器通过分配时间片 让任务执行一段时间 切换到另一个任务再运行一段时间 不同任务交替往复执行
并行代表计算机能够同时执行多项任务多核处理器在不同的核心上并行的执行任务
多线程编程典型实现异步的方式多核环境每个线程被分配到独立的核心上运行
应用于视频图像处理、科学计算
单线程编程单个脚本只能在一个线程上运行 (主线程)JS 引擎有多个线程
同步任务 Sync未被引擎挂起 在主线程上排队的任务前一个任务执行完才能执行下个任务
也可理解为同步任务就是可以直接拿到结果
异步任务 Async被引擎挂起 不进入主线程而进入任务队列的任务异步任务就是不能直接拿到结果
需要通过轮询或者回调来拿到结果
事件循环循环检查异步任务是否可进入主线程的机制挂起处于等待的任务 先执行排在后面的任务
等异步操作返回结果 再回头继续执行挂起的任务
任务队列JS 引擎提供的需要当前程序处理的异步任务

单线程

JS 执行环境内容缺点
单线程一次只能完成一件任务。
如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推
有耗时长的任务需排队 拖延程序执行
解决此问题的方案是 JS语言将任务的执行模式分为同步和异步