1. 程式人生 > 其它 >封裝ajax請求

封裝ajax請求

技術標籤:javascript

封裝ajax請求:
定義函式ajax,封裝ajax4步:

	function ajax(){
		//建立xhr物件
		//繫結onreadystatechange事件處理函式
		//如果有引數,將引數拼接url末尾
		//開啟連線(url,type)
		//如果是post,修改請求頭
		//如果是get, send()
		//否則 send(引數)
	}
	//url:服務端地址
	//type:請求的型別get/post
	//data:引數可有可無
	datatype:返回資料的型別,如果返回的不是json,就不填
	如果返回的是json,就寫明json,寫明json後,ajax函式內會自動將json轉為js物件
	//強行訪問物件中一個不存在的屬性時,不會報錯,而是返回undefined
//解構失敗返回undefined不報錯 //引數解構:其實就是物件解構在傳參時的應用而已 function ajax({形參 url:url, type:type, data:data, dataType:dataType }){ console.log(`向${url}傳送${type}請求`); if(data!=undefined&&type=="get"){...} if(data!=undefined&&type=="post"){...} if(dataType=="json"
){...} }

物件解構的方式一對一的,剩餘引數rest不會按順序傳參,雖然可以應對多個引數不確定的情況
預設值:只能應對結尾一個引數不確定時
引數解構:在函式中傳參時,將一個大的物件,打散後,傳遞給對應的形參變數
定義時:所有形參變數都要定義在一個物件內,呼叫時,所有實參值都要放在一個物件解構中整體傳入

封裝ajax:
要封裝一個函式,儲存重用的程式碼
1.程式碼中所有不確定的,都應該定義為形參變數
2.所有不一定執行的程式碼,都要加判斷條件
四個引數:
1.url:要請求的目標服務端介面地址
2.type:不同的請求型別
3.callback:是呼叫者自定義的一個函式,會在呼叫時提前傳入ajax函式內部 ,而不是立刻執行,是等響應回來後自動執行,因為把calback寫在了onreadystatechange中

4.data:要傳送的引數,要求是:變數1=值1&&變數2=值2,不帶問號且必須是字串
強調:回撥函式,都是需要的,因為響應結果都要處理
但不是所有請求都帶引數
data有時候需要,有時候沒有,凡是可能有可能沒有的形參,都必須放在形參列表的結尾
因為函式呼叫時,中間是不能缺引數的
比如ajax(url,type,callback),沒有第四個data引數值,則ajax內的data變數獲得的就是Undefined
ajax(url,type,,callback)就會出現預編譯錯誤

	function ajax(url,type,callback,data){
		var xhr=new XMLHttpRequest();
		//如果傳送get請求時帶引數
		if(type="get"&&data!==undefined){
			//需要將引數用?連線url地址結尾
			url+="?"+data;
		}
		xhr.open(type,url,true);
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4){
				var result=JSON.Parse(xhr.responseText);
				//缺少一段自定義的程式碼來對result執行不同的操作
				//只要一段程式碼不確定時,也可以用形參變數來解決
				//只不過這個形參變數將來傳入的不是一個值,而是一個函式
				callback(result);
			}
		}
		if(type=="post"){
			//只有傳送post請求時,才需要新增請求頭
			xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"html);
		}
		if(type=="post"){
			//只有post請求,才會將引數放在send()中傳送
			xhr.send(data);
		}else{
			//如果是get請求,send()中什麼都沒有
			xhr.send();
		}
	}

利用封裝的ajax:
在html網頁中如何獲得a,b,c商品的總和,考慮程式完成的總時間最少
假設有一個伺服器端介面,可根據條件分別查詢三種商品的數量
http://localhost:5050/?type=a,b,c
分別返回a類,b類,c類商品的總數
每個介面,因為數量很大,所以可能有3秒的返回延遲
可執行server.js測試介面
需求:程式完成的總時間最少
現只有一個已封裝的基本ajax函式

	function ajax({url,type="get",data}){
		return new Promise(function(resolve,reject){
			var xhr=new XMLHttpRequest();
			if(type="get"&&data!==undefined){
				url+="?"+data
			}
			xhr.open(type,url,true);
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4){
					var result=JSON.Parse(xhr.responseText);
					resolve(result);
				}
			}
			if(type="post"){
				xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
			}
			if(type="post"){
				xhr.send(data);
			}else{
				xhr.send();
			}
		})
	}

建立伺服器server.js

	const http=require('http');
	const url=require('url');
	http.createServer((req,res)=>{
		var type=url.parse(req.url,true).query.type;
		res.writHead(200,{
			"Access-Control-Allow-Origin":"*"
		})
		if(type="a"){
			res.write(JSON.stringify({type:'a',count:30}));
		}else if(type="b"){
			res.write(JSON.stringify({type:'b',count:20}));
		}else if(type="c"){
			res.write(JSON.stringify({type:'c',count:50}));
		}
		setTimeout(()=>{
			res.end();
		},3000)
	}).listen(5050);

1.第一種方法 Promise.all

	引入ajax.js
	var total=0;
	Promise.all([
		ajax({
			url:"http:localhost:5050",
			data:"type=a"
		}),
		ajax({
			url:"http:localhost:5050",
			data:"type=b"
		}),
		ajax({
			url:"http:localhost:5050",
			data:"type=c"
		}),
	]).then(arr=>{
		for(var obj of arr){
			total+=obj.count;
		}
		console.log(total);
	})

2.第二種Es7

	引入ajax.js
	var total==0;
	(async function(){
		var arr=await Promise.all([
			ajax({
			url:"http:localhost:5050",
			data:"type=a"
		}),
		ajax({
			url:"http:localhost:5050",
			data:"type=b"
		}),
		ajax({
			url:"http:localhost:5050",
			data:"type=c"
		}),
		]);
		for(var obj of arr){
			total+=obj.count;
		}
		console.log(total);
	})();