1. Vue前端互動
介面呼叫的方式有哪些?
- 原生ajax
- 基于jQuery的ajax
- Fetch
- Promise
url地址格式有哪些?
- 傳統的url
- Restful形式的url
1.1 異步
JavaScript的執行環境是「單執行緒」
所謂單執行緒,是指JS引擎中負責解釋和執行JavaScript代碼的執行緒只有一個,也就是一次只能完成一項任務,這 個任務執行完后才能執行下一個,它會「阻塞」其他任務,這個任務可稱為主執行緒
異步模式可以一起執行多個任務
JS中常見的異步呼叫
- 定時任何
- ajax
- 事件函式
1.2 promise
主要解決異步深層嵌套的問題 promise
提供了簡潔的API 使得異步操作更加容易
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/vue.js"></script>
<script type="text/javascript">
/*
1. Promise基本使用
我們使用new來構建一個Promise Promise的建構式接收一個引數,是函式,并且傳入兩個引數:
resolve,reject, 分別表示異步操作執行成功后的回呼函式和異步操作執行失敗后的回呼函式
*/
var p = new Promise(function(resolve, reject){
//2. 這里用于實作異步任務 setTimeout
setTimeout(function(){
var flag = false;
if(flag) {
//3. 正常情況
resolve('hello');
}else{
//4. 例外情況
reject('出錯了');
}
}, 100);
});
// 5 Promise實體生成以后,可以用then方法指定resolved狀態和reject狀態的回呼函式基于Promise發送Ajax請求Promise 基本API
// 在then方法中,你也可以直接return資料而不是Promise物件,在后面的then中就可以接收到資料了
p.then(function(data){
console.log(data)
},function(info){
console.log(info)
});
</script>
</body>
</html>
執行效果:

只要將代碼中的flag值改成true,就會顯示hello,

1.3 基于Promise發送Ajax請求
Promise可以幫我們解決Ajax請求執行順序的問題,可以將嵌套的復雜代碼,修改為鏈式代碼,
玩ajax需要安裝node.js,自己百度,
index.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
// 處理靜態資源
app.use(express.static('public'))
// 處理引數
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 設定允許跨域訪問該服務
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Headers', 'mytoken');
next();
});
// 路由
app.get('/data', (req, res) => {
res.send('Hello World!')
})
app.get('/data1', (req, res) => {
setTimeout(function(){
res.send('Hello TOM!')
},1000);
})
app.get('/data2', (req, res) => {
res.send('Hello JERRY!')
})
// 啟動監聽
app.listen(3000, () => {
console.log('running...')
})
運行index.js:

執行效果:

可以看到,我們可以輕松的控制多個ajax請求的順序了,
1.4 Promise常用API
.then():得到異步任務正確的結果
thrn引數中的函式回傳值:
1.回傳Promise實體物件
回傳的該實體物件會呼叫的下一個then
2.回傳普通值
回傳的普通值會傳遞給下一個then,通過then引數中函式的引數接收該值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
then引數中的函式回傳值
*/
function queryData(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
// 處理正常的情況
resolve(xhr.responseText);
}else{
// 處理例外情況
reject('服務器錯誤');
}
};
xhr.open('get', url);
xhr.send(null);
});
}
queryData('http://localhost:3000/data')
.then(function(data){
return queryData('http://localhost:3000/data1');
})
.then(function(data){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve(123);
},1000)
});
})
.then(function(data){
return 'hello';
})
.then(function(data){
console.log(data)
})
</script>
</body>
</html>
執行的效果:

.catch():獲取例外資訊
.finally():成功與否都會執行(不是正式標準)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
Promise常用API-實體方法
*/
// console.dir(Promise);
function foo() {
return new Promise(function(resolve, reject){
setTimeout(function(){
// resolve(123);
reject('error');
}, 100);
})
}
// foo()
// .then(function(data){
// console.log(data)
// })
// .catch(function(data){
// console.log(data)
// })
// .finally(function(){
// console.log('finished')
// });
// --------------------------
// 兩種寫法是等效的
foo()
.then(function(data){
console.log(data)
},function(data){
console.log(data)
})
.finally(function(){
console.log('finished')
});
</script>
</body>
</html>
執行的效果:
.all():
Promise.all方法接受一個陣列作引數,陣列中的物件(p1、p2、p3)均為promise實體(如果不是一個promise,該項會被用Promise.resolve轉換為一個promise),它的狀態由這三個promise實體決定,
.race():
Promise.race 方法同樣接受一個陣列作引數,當p1, p2, p3中有一個實體的狀態發生改變(變為fulfilled或rejected),p的狀態就跟著改變,并把第一個改變狀態的promise的回傳值,傳給p的回呼函式,
index.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
// 處理靜態資源
app.use(express.static('public'))
// 處理引數
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 設定允許跨域訪問該服務
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Headers', 'mytoken');
next();
});
app.get('/a1', (req, res) => {
setTimeout(function(){
res.send('Hello TOM!')
},1000);
})
app.get('/a2', (req, res) => {
setTimeout(function(){
res.send('Hello JERRY!')
},2000);
})
app.get('/a3', (req, res) => {
setTimeout(function(){
res.send('Hello SPIKE!')
},3000);
})
// 啟動監聽
app.listen(3000, () => {
console.log('running...')
})
html代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
Promise常用API-物件方法
*/
// console.dir(Promise)
function queryData(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
// 處理正常的情況
resolve(xhr.responseText);
}else{
// 處理例外情況
reject('服務器錯誤');
}
};
xhr.open('get', url);
xhr.send(null);
});
}
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a2');
var p3 = queryData('http://localhost:3000/a3');
// all 中的引數 [p1,p2,p3] 和 回傳的結果一 一對應["HELLO TOM", "HELLO JERRY","HELLO SPIKE"]
// Promise.all([p1,p2,p3]).then(function(result){
// console.log(result)
// })
Promise.race([p1,p2,p3]).then(function(result){
// 由于p1執行較快,Promise的then()將獲得結果'P1',p2,p3仍在繼續執行,但執行結果將被丟棄,
console.log(result)
})
</script>
</body>
</html>
執行效果:

還有就是執行所有

1.5 Fetch
Fetch API是新的ajax解決方案 Fetch會回傳Promise
fetch不是ajax的進一步封裝,而是原生js,沒有使用XMLHttpRequest物件,
fetch(url, options).then()
index.js:
app.get('/fdata', (req, res) => {
res.send('Hello Fetch!')
})
html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
Fetch API 基本用法
*/
fetch('http://localhost:3000/fdata').then(function(data){
// text()方法屬于fetchAPI的一部分,它回傳一個Promise實體物件,用于獲取后臺回傳的資料
return data.text();
}).then(function(data){
console.log(data);
})
</script>
</body>
</html>
執行效果:

1.5.1 fetch API中的HTTP請求
index.js:
app.get('/books', (req, res) => {
res.send('傳統的URL傳遞引數!' + req.query.id)
})
app.get('/books/:id', (req, res) => {
res.send('Restful形式的URL傳遞引數!' + req.params.id)
})
app.delete('/books/:id', (req, res) => {
res.send('DELETE請求傳遞引數!' + req.params.id)
})
app.post('/books', (req, res) => {
res.send('POST請求傳遞引數!' + req.body.uname + '---' + req.body.pwd)
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
Fetch API 呼叫介面傳遞引數
*/
// GET引數傳遞-傳統URL
// fetch('http://localhost:3000/books?id=123', {
// method: 'get'
// })
// .then(function(data){
// return data.text();
// }).then(function(data){
// console.log(data)
// });
// GET引數傳遞-restful形式的URL
// fetch('http://localhost:3000/books/456', {
// method: 'get'
// })
// .then(function(data){
// return data.text();
// }).then(function(data){
// console.log(data)
// });
// DELETE請求方式引數傳遞
// fetch('http://localhost:3000/books/789', {
// method: 'delete'
// })
// .then(function(data){
// return data.text();
// }).then(function(data){
// console.log(data)
// });
// POST請求傳參
fetch('http://localhost:3000/books', {
method: 'post',
body: 'uname=lisi&pwd=123',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
</script>
</body>
</html>
執行效果:

1.5.2 fetch API中回應格式
用fetch來獲取資料,如果回應正常回傳,我們首先看到的是一個response物件,其中包括回傳的一堆原始位元組,這些位元組需要在收到后,需要我們通過呼叫方法將其轉換為相應格式的資料,比如JSON ,BLOB或者TEXT等等,
index.js:
app.get('/json', (req, res) => {
res.json({
uname: 'lisi',
age: 13,
gender: 'male'
});
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript">
/*
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)
})
</script>
</body>
</html>
執行效果:

1.6 axios
axios(官網:https://github.com/axios/axios)是一個基于Promise用于瀏覽器和node.js的HTTP客戶端,
支持瀏覽器和node.js
支持promise
能攔截請求和回應
自動轉換JSON資料
能轉換請求和回應資料
從官網下載下來:


1.6.1 axios的基本用法
get和delete請求傳遞引數
- 通過傳統的url以?的形式傳遞引數
- restful形式傳遞引數
- 通過params形式傳遞引數
post和put請求傳遞引數
- 通過選項傳遞引數
- 通過URLSearchParams傳遞引數
index.js:
app.get('/adata', (req, res) => {
res.send('Hello axios!')
})
html:
<html> <head> <meta charset="UTF-8"> <title>Vue的基本使用</title> </head> <body> <script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script> <script type="text/javascript"> axios.get('http://localhost:3000/adata').then(function(ret){ // 注意data屬性是固定的用法,用于獲取后臺的實際資料 // console.log(ret.data) console.log(ret) }) </script> </body> </html>
執行效果:

1.6.2 axios請求傳參
index.js:
app.get('/axios', (req, res) => {
res.send('axios get 傳遞引數' + req.query.id)
})
app.get('/axios/:id', (req, res) => {
res.send('axios get (Restful) 傳遞引數' + req.params.id)
})
app.delete('/axios', (req, res) => {
res.send('axios get 傳遞引數' + req.query.id)
})
app.post('/axios', (req, res) => {
res.send('axios post 傳遞引數' + req.body.uname + '---' + req.body.pwd)
})
app.put('/axios/:id', (req, res) => {
res.send('axios put 傳遞引數' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script>
<script type="text/javascript">
/*
axios請求引數傳遞
*/
// axios get請求傳參
// axios.get('http://localhost:3000/axios?id=123').then(function(ret){
// console.log(ret.data)
// })
// axios.get('http://localhost:3000/axios/123').then(function(ret){
// console.log(ret.data)
// })
// axios.get('http://localhost:3000/axios', {
// params: {
// id: 789
// }
// }).then(function(ret){
// console.log(ret.data)
// })
// axios delete 請求傳參
// axios.delete('http://localhost:3000/axios', {
// params: {
// id: 111
// }
// }).then(function(ret){
// console.log(ret.data)
// })
axios.post('http://localhost:3000/axios', {
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
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)
})
</script>
</body>
</html>
執行效果:

1.6.3 axios回應結果與全域配置
相應結果的主要屬性:
data:實際回應回來的資料
headers:回應頭資訊
status:回應狀態碼
statusText:回應狀態資訊
全域配置資訊:
配置公共的請求頭 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';
index.js:
app.get('/axios-json', (req, res) => {
res.json({
uname: 'lisi',
age: 12
});
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script>
<script type="text/javascript">
/*
axios 回應結果與全域配置
*/
axios.get('http://localhost:3000/axios-json').then(function(ret){
console.log(ret.data.uname)
})
// 配置請求的基準URL地址
axios.defaults.baseURL = 'http://localhost:3000/';
// 配置請求頭資訊
axios.defaults.headers['mytoken'] = 'hello';
axios.get('axios-json').then(function(ret){
console.log(ret.data.uname)
})
</script>
</body>
</html>
執行效果:

1.6.4 axios攔截器
請求攔截器:
請求攔截器的作用是在請求發送前進行一些操作 例如在每個請求體里加上token,統一做了處理如果以后要改也非常容易,
回應攔截器:
回應攔截器的作用是在接收到回應后進行一些操作 例如在服務器回傳登錄狀態失效,需要重新登錄的時候,跳轉到登錄頁,
index.js:
app.get('/adata', (req, res) => {
res.send('Hello axios!')
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script>
<script type="text/javascript">
/*
axios攔截器
*/
// 1. 請求攔截器
axios.interceptors.request.use(function(config) {
console.log(config.url)
// 1.1 任何請求都會經過這一步 在發送請求之前做些什么
config.headers.mytoken = 'nihao';
// 1.2 這里一定要return 否則配置不成功
return config;
}, function(err){
console.log(err)
})
// 2. 回應攔截器
axios.interceptors.response.use(function(res) {
console.log(res)
// 2.1 在接收回應做些什么
var data =https://www.cnblogs.com/liuhui0308/p/ res.data;
return data;
}, function(err){
//2.2 對回應錯誤做點什么
console.log(err)
})
axios.get('http://localhost:3000/adata').then(function(data){
console.log(data)
})
</script>
</body>
</html>
執行效果:

1.6.5 async和await
async作為一個關鍵字放到函式前面
- 任何一個async函式都會隱式回傳一個promise
await關鍵字只能在使用async定義的函式中使用
- await后面可以直接跟一個Promise實體物件
- await函式不能單獨使用
async/await讓異步代碼看起來、表現起來更像同步代碼
index.js:
app.get('/async1', (req, res) => {
res.send('hello1')
})
app.get('/async2', (req, res) => {
if(req.query.info == 'hello') {
res.send('world')
}else{
res.send('error')
}
})
html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script>
<script type="text/javascript">
/*
async/await 處理異步操作:
async函式回傳一個Promise實體物件
await后面可以直接跟一個 Promise實體物件
*/
axios.defaults.baseURL = 'http:localhost:3000';
// axios.get('adata').then(function(ret){
// console.log(ret.data)
// })
// async function queryData() {
// var ret = await axios.get('adata');
// // console.log(ret.data)
// return ret.data;
// }
//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)
})
</script>
</body>
</html>
執行效果:

html:
<html>
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<script type="text/javascript" src="https://www.cnblogs.com/liuhui0308/p/js/axios.js"></script>
<script type="text/javascript">
/*
async/await處理多個異步任務
*/
//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)
})
</script>
</body>
執行效果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/934.html
標籤:JavaScript
