前言:為了深入理解jQuery中的ajax方法,本文通過使用原生JavaScript來封裝一個類似的方法,能實現(xiàn)最基本的功能。其中會使用帶promise方法。
1、ajax 的 基本功能
首先:
request = new XMLHttpRequest()
- JS 可以設(shè)置任意請求 header :
- 第一部分
request.open('get', '/xxx') - 第二部分
request.setRequestHeader('content-type','x-www-form-urlencoded') - 第四部分
request.send('a=1&b=2')
- 第一部分
- JS 可以獲取任意響應(yīng) header 嗎
- 第一部分
response.status/request.statusText - 第二部分
response.getResponseHeader()/request.getAllResponseHeaders() - 第四部分
response.responseText
- 第一部分
2、初始版本
封裝:
window.jQuery.ajax = function(options){
let method = options.method
let url = options.url
let headers = options.headers
let body = options.body
let failFn = options.failFn
let successFn = options.successFn
let request = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
request.setRequestHeader(key,headers[key])
}
request.onreadystatechange = function(){
if(request.readyState === 4){
if(request.status >=200 && request.status < 400){
successFn.call(undefined,request.responseText)
}else{
failFn.call(undefined,request.status)
}
}
}
request.send(body)
}
調(diào)用:
jQuery.ajax({
url:'/xxx',
method: 'post',
headers:{'Content-Type':'application/x-www-form-urlencoded',enoch:18},
body:'a=1&b=2',
successFn:(e)=>{console.log(e)},
failFn:(e)=>{console.log(e)}
})
3、使用ES6新語法優(yōu)化
- 上面的代碼中,好幾行的
let賦值看起來很傻,所以可以使用ES6的新語法:解構(gòu)賦值來進(jìn)行優(yōu)化。 - 首先簡單的介紹一下ES6新語法之解構(gòu)賦值,MDN文檔 。
解構(gòu)賦值語法是一個 Javascript 表達(dá)式,這使得可以將值從數(shù)組或屬性從對象提取到不同的變量中。舉例說明:
// ES6 解構(gòu)賦值示例
let a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20
// Stage 3 proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); //{c: 30, d: 40}
// 對象中的key值使用變量
var x = 'a' // 讓obj中的x為'a'
var obj = {
[x]:2
}
console.log(obj) // {a: 2}
- 更改后的代碼:
window.jQuery.ajax = function({method,url,headers,body,failFn,successFn}){
let request = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
request.setRequestHeader(key,headers[key])
}
request.onreadystatechange = function(){
if(request.readyState === 4){
if(request.status >=200 && request.status < 400){
successFn.call(undefined,request.responseText)
}else{
failFn.call(undefined,request.status)
}
}
}
request.send(body)
}
4、使用promise優(yōu)化
這里使用
promise優(yōu)化,主要解決的問題是:因為每個程序員的回調(diào)名不一樣,你不看文檔根本不知道這個庫的函數(shù)名是什么,所以我們可以使用該方法不設(shè)置successFn、failFn這兩個函數(shù)的函數(shù)名。優(yōu)化后代碼如下:
封裝:
window.jQuery.ajax = function({method,url,headers,body}){
return new Promise(function(resolve,reject){
let request = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
request.setRequestHeader(key,headers[key])
}
request.onreadystatechange = function(){
if(request.readyState === 4){
if(request.status >=200 && request.status < 400){
resolve.call(undefined,request.responseText)
}else{
reject.call(undefined,request.status)
}
}
}
request.send(body)
})
}
調(diào)用:
jQuery.ajax({
url:'/xxx',
method: 'post',
headers:{'Content-Type':'application/x-www-form-urlencoded',enoch:18},
body:'a=1&b=2',
}).then(
(e)=>{console.log(e)},
(e)=>{console.log(e)}
)
5、真正的jQuery的ajax方法
jQuery.ajax()方法中,和我上面自己實現(xiàn)的有些許的名稱差異:
- successFn ==>
success - failFn ==>
error - headers中設(shè)置響應(yīng)頭的Content-Type屬性 ==>
dataType - data ==>
body - jQuery也支持promise寫法(成功第一個參數(shù),失敗第二個參數(shù))
- 等等
舉例說明:
- jQuery普通寫法:
jQuery.ajax({
url:'/xxx',
method: 'post',
dataType:'x-www-form-urlencoded',
data:'a=1&b=2',
success:(e)=>{console.log(e)},
error:(e)=>{console.log(e)}
})
- jQuery
promise寫法:
jQuery.ajax({
url:'/xxx',
method: 'post',
dataType:'json',
data:'a=1&b=2',
}).then(
(e)=>{console.log(e)}, // 此時返回的是響應(yīng)的responseText 的JSON.parse()的結(jié)果,即一個對象
(e)=>{console.log('error')}
)