fetch基本使用
-
1.什么是fetch?
- 和Ajax一樣都是用于請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)的
- fetch是ES6中新增的,基于Promise的網(wǎng)絡(luò)請(qǐng)求方法
-
2.fetch基本使用
- fetch(url, {options}).then().catch();
- GET請(qǐng)求
// PHP文件:
<?php
$teacher = $_GET["teacher"];
$age = $_GET["age"];
$arr = array("name"=>$teacher, "age"=>$age);
$data = json_encode($arr);
echo $data;
fetch("http://127.0.0.1/jQuery/Ajax/41.php?teacher=lnj&age=34", {
method: "get"
}).then(function (res) {
// console.log(res.text());
// return res.text(); // 用這個(gè)返回,那么返回的是字符串
return res.json(); // 返回的是對(duì)象
}).then(function (data) {
console.log(data);
console.log(typeof data); // object
}).catch(function (e) {
console.log(e);
});
- POST請(qǐng)求
// PHP文件:
<?php
$rws_post = $GLOBALS["HTTP_RAW_POST_DATA"];
$mypost = json_decode($rws_post);
$teacher = (string)$mypost->teacher;
$age = (string)$mypost->age;
$arr = array("name"=>$teacher, "age"=>$age);
$data = json_encode($arr);
echo $data;
fetch("http://127.0.0.1/jQuery/Ajax/41.php", {
method: "post",
body: JSON.stringify({teacher:"zq", age:666})
}).then(function (res) {
// console.log(res.text());
// return res.text();
return res.json();
}).then(function (data) {
console.log(data);
console.log(typeof data);
}).catch(function (e) {
console.log(e);
});
fetch簡(jiǎn)單封裝(理解)
class EasyHttp{
static obj2str(data) {
data = data || {};
data.t = new Date().getTime();
var res = [];
for(var key in data){
res.push(encodeURIComponent(key)+"="+encodeURIComponent(data[key]));
}
return res.join("&");
}
static get(url, params){
return new Promise(function (resolve, reject) {
let newUrl = url;
if(params !== undefined && params instanceof Object){
let str = EasyHttp.obj2str(params);
newUrl += "?" + str;
}
fetch(newUrl, {
method: "get"
}).then(function (res) {
resolve(res.json());
}).catch(function (e) {
reject(e);
})
})
}
static post(url, params){
return new Promise(function (resolve, reject) {
fetch(url, {
method: "post",
body: JSON.stringify(params)
}).then(function (res) {
resolve(res.json());
}).catch(function (e) {
reject(e);
})
})
}
}
axios網(wǎng)絡(luò)請(qǐng)求庫(kù)
-
1.什么是axios?
- Axios 是一個(gè)基于promise的HTTP庫(kù)網(wǎng)絡(luò)請(qǐng)求插件
- 替代fetch
-
2.axios特點(diǎn)
- 2.1可以用在瀏覽器和 node.js 中
- 2.2支持 Promise API
- 2.3自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)
- 2.4客戶端支持防御 XSRF
備注:
axion使用中文檔:https://www.kancloud.cn/yunye/axios/234845
// get 測(cè)試:
<?php
//echo 'it666';
$teacher = $_GET["teacher"];
$age = $_GET["age"];
$arr = array("name"=>$teacher, "age"=>$age);
$data = json_encode($arr);
echo $data;
?>
<script>
// axios.get("http://127.0.0.1/jQuery/Ajax/41.php")
axios.get("http://127.0.0.1/jQuery/Ajax/41.php?teacher=lnj&age=34")
.then(function (res) {
console.log(res.data);
})
.catch(function (e) {
console.log(e);
});
</script>
// post測(cè)試:
<?php
$rws_post = $GLOBALS["HTTP_RAW_POST_DATA"];
$mypost = json_decode($rws_post);
$teacher = (string)$mypost->teacher;
$age = (string)$mypost->age;
$arr = array("name"=>$teacher, "age"=>$age);
$data = json_encode($arr);
echo $data;
?>
<script>
axios.post("http://127.0.0.1/jQuery/Ajax/41.php", {
teacher: "lnj",
age: 666
})
.then(function (res) {
console.log(res.data);
})
.catch(function (e) {
console.log(e);
});
</script>
-
3.全局的 axios 默認(rèn)值
- 在企業(yè)開(kāi)發(fā)中項(xiàng)目分為 :開(kāi)發(fā)階段和部署階段, 這兩個(gè)階段項(xiàng)目存儲(chǔ)的位置是不同的
- 項(xiàng)目上線前存儲(chǔ)在企業(yè)內(nèi)部測(cè)試服務(wù)器上,項(xiàng)目上線后存儲(chǔ)在企業(yè)正式服務(wù)器上
- 所以如果每次請(qǐng)求都將請(qǐng)求的地址寫在請(qǐng)求中, 那么項(xiàng)目上線時(shí)需要大量修改請(qǐng)求地址
- 為了解決這個(gè)問(wèn)題,我們可以配置一個(gè)全局URL根地址, 項(xiàng)目上線時(shí)只需要修改根地址即可
示例:
上線前地址是: http://127.0.0.1/jQuery/Ajax/41.php
上線后地址是: http://192.199.13.14/jQuery/Ajax/41.php
axios.defaults.timeout = 2000; // 2秒未執(zhí)行完励稳,報(bào)超時(shí)
axios.defaults.baseURL = "http://127.0.0.1"; // 設(shè)置根地址
axios.post("/jQuery/Ajax/41.php", // 設(shè)置相對(duì)路徑
{
teacher: "lnj",
age: 666
})
.then(function (res) {
console.log(res.data);
})
.catch(function (e) {
console.log(e);
});
Symbol基本概念
-
1.什么Symbol?
- Symbol是ES6中新增的一種數(shù)據(jù)類型,被劃分到了基本數(shù)據(jù)類型中
- 基本數(shù)據(jù)類型:
- 字符串、數(shù)值、布爾惩阶、undefined蜈亩、null武花、Symbol
- 引用數(shù)據(jù)類型: Object
-
2.Symbol的作用
- 用來(lái)表示一個(gè)獨(dú)一無(wú)二的值
-
3.如果生成一個(gè)獨(dú)一無(wú)二的值?
- 格式:let xxx = Symbol();
-
4.為什么需要Symbol?
- 在企業(yè)開(kāi)發(fā)中如果需要對(duì)一些第三方的插件、框架進(jìn)行自定義的時(shí)候远舅,可能會(huì)因?yàn)樘砑恿送膶傩曰蛘叻椒?將框架中原有的屬性或者方法覆蓋掉。為了避免這種情況的發(fā)生,框架的作者或者我們就可以使用Symbol作為屬性或者方法的名稱
// 測(cè)試:
let name = Symbol("name");
let say = Symbol("say");
let obj = {
// 注意點(diǎn): 如果想使用變量作為對(duì)象屬性的名稱, 那么必須加上[]
[name]: "lnj",
[say]: function () {
console.log("say");
}
}
// obj.name = "it666";
obj[Symbol("name")] = "it666";
console.log(obj);
注意點(diǎn):
如果想使用變量作為對(duì)象屬性的名稱,那么必須加上[]
- 5.如何區(qū)分Symbol?
- 在通過(guò)Symbol生成獨(dú)一無(wú)二的值時(shí)可以設(shè)置一個(gè)標(biāo)記
- 這個(gè)標(biāo)記僅僅用于區(qū)分, 沒(méi)有其它任何含義
Symbol注意點(diǎn)
- 1.通過(guò)Symbol生成獨(dú)一無(wú)二值時(shí)需要在后面加上(), 但是前面不能加new, 因?yàn)樗皇且妙愋?/li>
let xxx = Symbol(); // 正確
let xxx = new Symbol(); // 錯(cuò)誤
- 2.通過(guò)Symbol生成獨(dú)一無(wú)二值時(shí)傳入的字符串僅僅是一個(gè)標(biāo)記, 方便我們閱讀代碼, 沒(méi)有其它任何意義
let xxx = Symbol("name"); // name無(wú)任何意義
- 3.做類型轉(zhuǎn)換的時(shí)候不能轉(zhuǎn)換成數(shù)值
let xxx = Symbol("name");
console.log(String(xxx)); // 可以轉(zhuǎn)換
console.log(Boolean(xxx)); // 可以轉(zhuǎn)換
console.log(Number(xxx)); // 報(bào)錯(cuò)痕钢,不可以轉(zhuǎn)換
- 4.不能做任何運(yùn)算
let xxx = Symbol("name");
console.log(xxx + "abc"); // 報(bào)錯(cuò)
console.log(xxx + 123); // 報(bào)錯(cuò)
- 5.Symbol生成的值作為屬性或方法名稱時(shí),一定要保存下來(lái), 否則后續(xù)無(wú)法使用
let name = Symbol("name");
let obj = {
[name]: "lnj"
// [Symbol("name")]: "it666" // 不在外面保存图柏,直接在對(duì)象里面創(chuàng)建是不行的
}
console.log(obj[name]);
// console.log(obj[Symbol("name")]); // 錯(cuò)誤示范
- 6.for循環(huán)無(wú)法遍歷出Symbol的屬性和方法
- Object.getOwnPropertySymbols(對(duì)象名稱),這樣才可以遍歷對(duì)象中的Symbol的屬性和方法任连,返回給我們一個(gè)數(shù)組
let name = Symbol("name");
let say = Symbol("say");
let obj = {
[name]: "lnj",
[say]: function () {
console.log("say");
},
age: 34,
gender: "man",
hi: function () {
console.log("hi");
}
}
// for(let key in obj){
// console.log(key); // 只會(huì)輸出age gender hi
// }
console.log(Object.getOwnPropertySymbols(obj)); // 這么寫才會(huì)輸出Symbol的屬性和方法
Iterator基本概念
-
1.什么是Iterator?
- Iterator又叫做迭代器, 是一種接口
- 這里的接口和現(xiàn)實(shí)中接口一樣,是一種標(biāo)準(zhǔn)蚤吹、一種規(guī)范
- 例如:電腦的USB接口有電腦USB接口的標(biāo)準(zhǔn)和規(guī)范,正是因?yàn)橛辛藰?biāo)準(zhǔn)和規(guī)范。所以A廠商生成的USB線可以插到B廠商電腦的USB接口上
- 它規(guī)定了不同數(shù)據(jù)類型統(tǒng)一訪問(wèn)的機(jī)制,這里的訪問(wèn)機(jī)制主要指數(shù)據(jù)的遍歷
- 在ES6中Iterator接口主要供for...of消費(fèi)
- Iterator又叫做迭代器, 是一種接口
-
2.默認(rèn)情況下以下數(shù)據(jù)類型都實(shí)現(xiàn)的Iterator接口
- Array/Map/Set/String/TypedArray/函數(shù)的 arguments 對(duì)象/NodeList 對(duì)象
let arr = [1, 3, 5];
console.log(arr[Symbol.iterator]);
let it = arr[Symbol.iterator]();
console.log(it);
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
for(let value of arr){
console.log(value); // 1 3 5
}
// let obj = {
// name: "lnj",
// age: 34,
// gender: "man"
// }
// console.log(obj[Symbol.iterator]);
// for(let value of obj){
// console.log(value); // 報(bào)錯(cuò),不支持對(duì)象
// }
- 3.實(shí)現(xiàn)Iterator接口
- 3.1只要一個(gè)數(shù)據(jù)已經(jīng)實(shí)現(xiàn)了Iterator接口, 那么這個(gè)數(shù)據(jù)就有一個(gè)叫做[Symbol.iterator]的屬性
- 3.2[Symbol.iterator]的屬性會(huì)返回一個(gè)函數(shù)
- 3.3[Symbol.iterator]返回的函數(shù)執(zhí)行之后會(huì)返回一個(gè)對(duì)象
- 3.4[Symbol.iterator]函數(shù)返回的對(duì)象中又一個(gè)名稱叫做next的方法
- 3.5next方法每次執(zhí)行都會(huì)返回一個(gè)對(duì)象{value: 1, done: false}
- 3.6這個(gè)對(duì)象中存儲(chǔ)了當(dāng)前取出的數(shù)據(jù)和是否取完了的標(biāo)記
- 自制Iterator接口
class MyArray{
constructor(){
for(let i = 0; i < arguments.length; i++){
// this[0] = 1;
// this[1] = 3;
// this[2] = 5;
this[i] = arguments[i];
}
this.length = arguments.length;
}
[Symbol.iterator](){
let index = 0;
let that = this;
return {
next(){
if(index < that.length){
return {value: that[index++], done: false}
}else{
return {value: that[index], done: true}
}
}
}
}
}
- 測(cè)試
let arr = new MyArray(1, 3, 5);
// console.log(arr[0]);
// arr[0] = 666;
// console.log(arr);
for(let value of arr){
console.log(value);
}
// console.log(arr[Symbol.iterator]);
let it = arr[Symbol.iterator]();
console.log(it);
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
- 實(shí)現(xiàn)支持對(duì)象的Iterator接口
// 示例:
let obj = {
name: "lnj",
age: 34,
gender: "man",
[Symbol.iterator](){
let keys = Object.keys(this);
// console.log(keys);
let index = 0;
let that = this;
return {
next(){
if(index < keys.length){
return {value: that[keys[index++]], done: false};
}else{
return {value: undefined, done: true};
}
}
}
}
}
//測(cè)試:
for(let value of obj){
console.log(value); // lnj 34 man
}
Iterator應(yīng)用場(chǎng)景
1.解構(gòu)賦值
2.擴(kuò)展運(yùn)算符
class MyArray{
constructor(){
for(let i = 0; i < arguments.length; i++){
// this[0] = 1;
// this[1] = 3;
// this[2] = 5;
this[i] = arguments[i];
}
this.length = arguments.length;
}
[Symbol.iterator](){
let index = 0;
let that = this;
return {
next(){
if(index < that.length){
return {value: that[index++], done: false}
}else{
return {value: that[index], done: true}
}
}
}
}
}
// 1.解構(gòu)賦值
// let arr = [1, 3];
let arr = new MyArray(1, 3);
let [x, y, z] = arr;
console.log(x, y, z); // 1 3 undefined
// 2.擴(kuò)展運(yùn)算符
// let arr1 = [1, 3];
// let arr2 = [2, 4];
let arr1 = new MyArray(1, 3);
let arr2 = new MyArray(2, 4);
let arr3 = [...arr1, ...arr2];
console.log(arr3); // [1,3,2,4]
Generator函數(shù)基本概念
-
1.什么是Generator函數(shù)?
- Generator函數(shù)是ES6提供的一種異步編程解決方案
- Generator函數(shù)內(nèi)部可以封裝多個(gè)狀態(tài),因此又可以理解為是一個(gè)狀態(tài)機(jī)
-
2.如何定義Generator函數(shù)
- 只需要在普通函數(shù)的function后面加上*即可
function* gen() {
}
- 3.Generator函數(shù)和普通函數(shù)區(qū)別
- 3.1調(diào)用Generator函數(shù)后,無(wú)論函數(shù)有沒(méi)有返回值, 都會(huì)返回一個(gè)迭代器對(duì)象,
- 3.2調(diào)用Generator函數(shù)后,函數(shù)中封裝的代碼不會(huì)立即被執(zhí)行
function* gen() {
console.log("123");
}
let it = gen();
console.log(it); // 無(wú)輸出
- 4.真正讓Generator具有價(jià)值的是yield關(guān)鍵字
- 4.1在Generator函數(shù)內(nèi)部使用yield關(guān)鍵字定義狀態(tài)
- 4.2并且yield關(guān)鍵字可以讓Generator內(nèi)部的邏輯能夠切割成多個(gè)部分课梳。
- 4.3通過(guò)調(diào)用迭代器對(duì)象的next方法執(zhí)行一個(gè)部分代碼,執(zhí)行哪個(gè)部分就會(huì)返回哪個(gè)部分定義的狀態(tài)
function* gen() {
console.log("123");
yield "aaa";
console.log("567");
yield 1 + 1;
console.log("789");
yield true;
}
let it = gen();
console.log(it.next()); // 123
console.log(it.next()); // 567
console.log(it.next()); // 789
注意點(diǎn):
yield關(guān)鍵字只能在Generator函數(shù)中使用,不能在普通函數(shù)中使用
- 5.在調(diào)用next方法的時(shí)候可以傳遞一個(gè)參數(shù),這個(gè)參數(shù)會(huì)傳遞給上一個(gè)yield
function* gen() {
console.log("123");
let res = yield "aaa";
console.log(res);
console.log("567");
yield 1 + 1;
console.log("789");
yield true;
}
let it = gen();
console.log(it.next()); // 123 {value: "aaa", done: false}
console.log(it.next("it666")); // it666 567 {value: 2, done: false}
console.log(it.next()); // 789 {value: true, done: false}
console.log(it.next()); // {value: undefined, done: true}
Generator函數(shù)應(yīng)用場(chǎng)景
- 1.讓函數(shù)返回多個(gè)值
/*
function calculate(a, b) {
let sum = a + b;
let sub = a - b;
return [sum, sub];
}
*/
function* calculate(a, b) {
yield a + b;
yield a - b;
}
let it = calculate(10, 5);
console.log(it.next().value);
console.log(it.next().value);
-
2.利用 Generator函數(shù)距辆,可以在任意對(duì)象上快速部署 Iterator 接口
- 對(duì)比Generator和Iterator
- Generator 函數(shù)特點(diǎn)
- 1.Generator 函數(shù)也是一個(gè)函數(shù)
- 2.Generator函數(shù)會(huì)返回一個(gè)迭代器對(duì)象
- 3.迭代器對(duì)象有next方法
- 4.next方法每次執(zhí)行都會(huì)返回一個(gè)對(duì)象{value: xxx, done: false}
- iterator特點(diǎn)
- 1.必須有一個(gè)叫做[Symbol.iterator]的屬性
- 2.[Symbol.iterator]的屬性會(huì)返回一個(gè)函數(shù)
- 3.[Symbol.iterator]返回的函數(shù)執(zhí)行之后會(huì)返回一個(gè)可迭代對(duì)象
- 4.[Symbol.iterator]函數(shù)返回的對(duì)象中又一個(gè)名稱叫做next的方法
- 5.next方法每次執(zhí)行都會(huì)返回一個(gè)對(duì)象{value: xxx, done: false}
- Generator 函數(shù)特點(diǎn)
- 對(duì)比Generator和Iterator
2.1iterator部署:
let obj = {
name: "lnj",
age: 34,
gender: "man",
[Symbol.iterator](){
let keys = Object.keys(this);
// console.log(keys);
let index = 0;
let that = this;
return {
next(){
if(index < keys.length){
return {value: that[keys[index++]], done: false};
}else{
return {value: undefined, done: true};
}
}
}
}
}
for(let value of obj){
console.log(value); // lnj 34 man
}
- 2.2Generator部署(==更方便,代碼更少==):
let obj = {
name: "lnj",
age: 34,
gender: "man"
}
function* gen(){
let keys = Object.keys(obj);
for(let i = 0; i < keys.length; i++){
yield obj[keys[i]];
}
}
obj[Symbol.iterator] = gen;
let it = obj[Symbol.iterator]();
console.log(it.next()); // lnj
console.log(it.next()); // 34
console.log(it.next()); // man
console.log(it.next()); // undefined
- 3.用同步的流程來(lái)表示異步的操作(實(shí)際工作中不會(huì)這么用暮刃,代碼更復(fù)雜跨算,僅作為了解)
function request() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("拿到的數(shù)據(jù)");
}, 1000);
});
}
/* 正常的寫法
request().then(function (data) {
console.log(data, 1);
return request();
}).then(function (data) {
console.log(data, 2);
return request();
}).then(function (data) {
console.log(data, 3);
});
*/
// 用同步的流程來(lái)表示異步的操作
function* gen() {
yield request();
yield request();
yield request();
}
let it = gen();
// console.log(it.next().value);
it.next().value.then(function (data) {
console.log(data, 1);
return it.next().value;
}).then(function (data) {
console.log(data, 2);
return it.next().value;
}).then(function (data) {
console.log(data, 3);
});
async函數(shù)
-
1.async函數(shù)
- async函數(shù)是ES8中新增的一個(gè)函數(shù),用于定義一個(gè)異步函數(shù)
- async函數(shù)函數(shù)中的代碼會(huì)自動(dòng)從上至下的執(zhí)行代碼
-
2.await操作符
- await操作符只能在異步函數(shù) async function 中使用
- await表達(dá)式會(huì)暫停當(dāng)前 async function 的執(zhí)行,等待 Promise 處理完成椭懊。
- 若 Promise正常處理(fulfilled)诸蚕,其回調(diào)的resolve函數(shù)參數(shù)作為await表達(dá)式的值,然后繼續(xù)執(zhí)行 async function氧猬。
- 上個(gè)知識(shí)點(diǎn)里用同步的流程來(lái)表示異步的操作:用Generator部署的代碼很麻煩背犯,不適用,但是可以用async函數(shù)來(lái)簡(jiǎn)化
function request() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("拿到的數(shù)據(jù)");
}, 1000);
});
}
async function gen() {
let res1 = await request();
console.log(res1, 1);
let res2 = await request();
console.log(res2, 2);
let res3 = await request();
console.log(res3, 3);
}
gen();