文章目錄
- 一、promise
- 1. 異步
- 2. Promise
- 3. 基于Promise發送Ajax請求
- 4. Promise 基本API
- 二、介面呼叫 fetch
- 三、介面呼叫 axios
- 1. axios 基礎用法
- 2. axios 全域配置
- 3. axios 攔截器
- 四、async 和 await
一、promise
1. 異步
-
JS 是但執行緒,一次只能執行一個任務,任務執行完后才能執行下一個,它會「阻塞」其他任務,這個任務可稱為主執行緒
-
JS中常見的異步呼叫
① 定時任務
② Ajax
③事件函式 -
異步模式可以一起執行多個任務,但是結果順序不確定,結果依賴于請求的這個程式的順序
-
如許要規定結果列印的順序就需要函式嵌套,但是函式嵌套會形成回呼地獄,于是就需要用到
promise
2. Promise
Promise 是異步編程的一種解決方案,Promise 是一個函式,函式也是物件,可以當作建構式 new 出來
使用:
- 先
new實體化Promise物件 - 再定義處理的方案,自定義名
resolve和reject處理成功和失敗,這兩個引數都是方法可以直接呼叫 - 然后通過
p.then處理結果
let p = new Promise(function (resolve, reject) {
setTimeout(function () {
let flag = false
if (flag) {
resolve(1);
} else {
reject(2);
}
}, 100)
})
p.then(function (data) {
console.log(data);
}, function (info) {
console.log(info);
})
3. 基于Promise發送Ajax請求
1.回傳promise實體物件
回傳的該實體物件會呼叫下一個 then
2.回傳普通值
如果 .then 回傳的是一個普通值,那么這個 then 會自動產生一個默認的 promise 物件,保證下一個 then 的使用,可以繼續進行鏈式操作
<script type="text/javascript">
/*
基于Promise發送Ajax請求
*/
function queryData(url) {
# 1.1 創建一個Promise實體
var p = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
# 1.2 處理正常的情況
resolve(xhr.responseText);
}else{
# 1.3 處理例外情況
reject('服務器錯誤');
}
};
xhr.open('get', url);
xhr.send(null);
});
return p;
}
# 注意: 這里需要開啟一個服務
# 在then方法中,你也可以直接return資料而不是Promise物件,在后面的then中就可以接收到資料了
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data)
# 1.4 想要繼續鏈式編程下去 需要 return
return queryData('http://localhost:3000/data1');
})
.then(function(data){
console.log(data);
return queryData('http://localhost:3000/data2');
})
.then(function(data){
console.log(data)
});
</script>
4. Promise 基本API
實體方法
-
.then()
得到異步任務正確的結果 -
.catch()
獲取例外資訊 -
.finally()
成功與否都會執行(不是正式標準)
靜態方法(物件方法)
.all()
并發處理多個異步任務,所有任務都執行完了才能得到結果
Promise.all方法接受一個陣列作引數,陣列中的物件(p1、p2、p3)均為promise實體(如果不是一個promise,該項會被用Promise.resolve轉換為一個promise),它的狀態由這三個promise實體決定
.race()
并發處理多個異步任務,只要有一個任務執行完了就能得到結果
Promise.race方法同樣接受一個陣列作引數,當p1, p2, p3中有一個實體的狀態發生改變(變為fulfilled或rejected),p的狀態就跟著改變,并把第一個改變狀態的promise的回傳值,傳給p的回呼函式
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a2');
var p3 = queryData('http://localhost:3000/a3');
Promise.all([p1,p2,p3]).then(function(result){
// all 中的引數 [p1,p2,p3] 和 回傳的結果一 一對應["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
})
Promise.race([p1,p2,p3]).then(function(result){
// 由于p1執行較快,Promise的then()將獲得結果'P1',p2,p3仍在繼續執行,但執行結果將被丟棄,
console.log(result) // "HELLO TOM"
})
二、介面呼叫 fetch
- Fetch API 是新的ajax解決方案
- fetch不是ajax的進一步封裝,而是原生js,沒有使用XMLHttpRequest物件
- fetch(url, options).then()
// 先用 then 的方式得到 text 的資料
fetch('/wwwww').then(data=>{
// text 是 fetch 的一部分 回傳值是一個 promise 實體物件 用于獲取后臺回傳的資料
return data.text()
// 然后通過下一個 then 得到具體的資料
}).then(ret=>{
console.log(ret);
})
fetch API 中的 HTTP 請求
- fetch(url, options).then()
- HTTP協議,它給我們提供了很多的方法,如POST,GET,DELETE,UPDATE,PATCH和PUT
- 默認的是 GET 請求
- 需要在 options 物件中 指定對應的 method method:請求使用的方法
- post 和 普通 請求的時候 需要在options 中 設定 請求頭 headers 和 body
//Fetch API 呼叫介面傳遞引數
//1.1 GET引數傳遞 - 傳統URL 通過url ? 的形式傳參
fetch('http://localhost:3000/books?id=123', {
// get 請求可以省略不寫 默認的是GET
method: 'get'
})
.then(function (data) {
// 它回傳一個Promise實體物件,用于獲取后臺回傳的資料
return data.text();
}).then(function (data) {
// 在這個then里面我們能拿到最終的資料
console.log(data)
});
//1.2 GET引數傳遞 restful形式的URL 通過/ 的形式傳遞引數 即 id = 456 和id后臺的配置有關
fetch('http://localhost:3000/books/456', {
// get 請求可以省略不寫 默認的是GET
method: 'get'
})
.then(function (data) {
return data.text();
}).then(function (data) {
console.log(data)
});
//2.1 DELETE請求方式引數傳遞 洗掉id 是 id=789
fetch('http://localhost:3000/books/789', {
method: 'delete'
})
.then(function (data) {
return data.text();
}).then(function (data) {
console.log(data)
});
//3 POST請求傳參
fetch('http://localhost:3000/books', {
method: 'post',
// 3.1 傳遞資料
body: 'uname=lisi&pwd=123',
// 3.2 設定請求頭
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function (data) {
return data.text();
}).then(function (data) {
console.log(data)
});
// POST請求傳參
fetch('http://localhost:3000/books', {
method: 'post',
body: JSON.stringify({
uname: '張三',
pwd: '456'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function (data) {
return data.text();
}).then(function (data) {
console.log(data)
});
// PUT請求傳參 修改id 是 123 的
fetch('http://localhost:3000/books/123', {
method: 'put',
body: JSON.stringify({
uname: '張三',
pwd: '789'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function (data) {
return data.text();
}).then(function (data) {
console.log(data)
});
fetchAPI 中 回應格式
text()將回傳體處理成字串型別json()回傳結果和JSON.parse(responseText)一樣- 用fetch來獲取資料,如果回應正常回傳,我們首先看到的是一個response物件,其中包括回傳的一堆原始位元組,這些位元組需要在收到后,需要我們通過呼叫方法將其轉換為相應格式的資料,比如
JSON,BLOB或者TEXT等等
//Fetch回應結果的資料格式
fetch('http://localhost:3000/json').then(function (data) {
// return data.json();
// 將獲取到的資料使用 json 轉換物件
return data.text();
}).then(function (data) {
// console.log(data.uname)
// console.log(typeof data)
var obj = JSON.parse(data);
console.log(obj.uname, obj.age, obj.gender)
})
三、介面呼叫 axios
- 基于promise用于瀏覽器和node.js的http客戶端
- 支持瀏覽器和node.js
- 支持promise
- 能攔截請求和回應
- 自動轉換JSON資料
- 能轉換請求和回應資料
1. axios 基礎用法
axios.get('/www')
.then(ret=>{
// data 的名字是固定的,它用于獲取后臺回應的資料
console.log(ret.data);
})
查詢資料 get
洗掉資料 delete
- 通過傳統的url 以 ? 的形式傳遞引數
- restful 形式傳遞引數
- 通過params 形式傳遞引數
添加資料 post
修改資料 put
- 通過選項傳遞引數
- 通過 URLSearchParams 傳遞引數
//# 1. 發送get 請求
axios.get('http://localhost:3000/adata').then(function (ret) {
//#拿到 ret 是一個物件 所有的物件都存在 ret 的data 屬性里面
// 注意data屬性是固定的用法,用于獲取后臺的實際資料
// console.log(ret.data)
console.log(ret)
})
//# 2. get 請求傳遞引數# 2.1 通過傳統的url 以 ? 的形式傳遞引數
axios.get('http://localhost:3000/axios?id=123').then(function (ret) {
console.log(ret.data)
})
//# 2.2 restful 形式傳遞引數
axios.get('http://localhost:3000/axios/123').then(function (ret) {
console.log(ret.data)
})
//# 2.3 通過params 形式傳遞引數
axios.get('http://localhost:3000/axios', {
params: {
id: 789
}
}).then(function (ret) {
console.log(ret.data)
})
//#3 axios delete 請求傳參 傳參的形式和 get 請求一樣
axios.delete('http://localhost:3000/axios', {
params: {
id: 111
}
}).then(function (ret) {
console.log(ret.data)
})
//# 4 axios 的 post 請求# 4.1 通過選項傳遞引數
axios.post('http://localhost:3000/axios', {
uname: 'lisi',
pwd: 123
}).then(function (ret) {
console.log(ret.data)
})
//# 4.2 通過 URLSearchParams 傳遞引數
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('http://localhost:3000/axios', params).then(function (ret) {
console.log(ret.data)
})
//#5 axios put 請求傳參 和 post 請求一樣
axios.put('http://localhost:3000/axios/123', {
uname: 'lisi',
pwd: 123
}).then(function (ret) {
console.log(ret.data)
})
2. axios 全域配置
// 配置公共的默認地址
axios.defaults.baseURL = 'https://api.example.com';
// 配置 超時時間
axios.defaults.timeout = 2500;
// 配置公共的請求頭
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 配置公共的 post 的 Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
3. axios 攔截器
請求攔截器
- 請求攔截器的作用是在請求發送前進行一些操作
- 例如在每個請求體里加上token,統一做了處理如果以后要改也非常容易
回應攔截器
- 回應攔截器的作用是在接收到回應后進行一些操作
- 例如在服務器回傳登錄狀態失效,需要重新登錄的時候,跳轉到登錄頁
//# 1. 請求攔截器
axios.interceptors.request.use(function (config) {
console.log(config.url)
//# 1.1 任何請求都會經過這一步 在發送請求之前做些什么
config.headers.mytoken = 'nihao';
//# 1.2 這里一定要return 否則配置不成功
return config;
}, function (err) {
//#1.3 對請求錯誤做點什么
console.log(err)
})
//#2. 回應攔截器
axios.interceptors.response.use(function (res) {
//#2.1 在接收回應做些什么
var data = res.data;
return data;
}, function (err) {
//#2.2 對回應錯誤做點什么
console.log(err)
})
四、async 和 await
async作為一個關鍵字放到函式前面
- 任何一個
async函式都會隱式回傳一個promise
await 關鍵字只能在使用 async 定義的函式中使用
- ? await后面可以直接跟一個 Promise實體物件
- ? await函式不能單獨使用
async/await 讓異步代碼看起來、表現起來更像同步代碼
//# 1. async 基礎用法
//# 1.1 async作為一個關鍵字放到函式前面
async function queryData() {
//# 1.2 await關鍵字只能在使用async定義的函式中使用 await后面可以直接跟一個 Promise實體物件
var ret = await new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('nihao')
}, 1000);
})
// console.log(ret.data)
return ret;
}
//# 1.3 任何一個async函式都會隱式回傳一個promise 我們可以使用then 進行鏈式編程
queryData().then(function (data) {
console.log(data)
})
//#2. async 函式處理多個異步函式
axios.defaults.baseURL = 'http://localhost:3000';
async function queryData() {
//# 2.1 添加await之后 當前的await 回傳結果之后才會執行后面的代碼
var info = await axios.get('async1');
//#2.2 讓異步代碼看起來、表現起來更像同步代碼
var ret = await axios.get('async2?info=' + info.data);
return ret.data;
}
queryData().then(function (data) {
console.log(data)
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/286328.html
標籤:其他
