回調(diào)地獄
封裝ajax的時候,發(fā)現(xiàn):請求成功后的值不能直接返回給調(diào)用者迷殿,而需要在其內(nèi)部執(zhí)行一個回調(diào)函數(shù)儿礼。如果在請求一次后需要再次請求,那么庆寺,也就是在回調(diào)函數(shù)中需要再次調(diào)用ajax蚊夫,再次傳入回調(diào)函數(shù),次數(shù)多了以后就形成了回調(diào)地獄懦尝。難以使用及維護
解決:es6中的構(gòu)造函數(shù)Promise解決這個問題知纷。
基本語法:
new Promise(function (resolve, reject) {
// resolve 表示成功的回調(diào)
// reject 表示失敗的回調(diào)
}).then(function (res) {
// 成功的函數(shù)
}).catch(function (err) {
// 失敗的函數(shù)
})
在promise中,提供了兩個參數(shù)陵霉,分別表示執(zhí)行成功和失敗的回調(diào)函數(shù)琅轧,執(zhí)行成功調(diào)用resolve,失敗調(diào)用reject即可踊挠,具體resolve和reject的執(zhí)行乍桂,分別在then和catch中冲杀。這樣可以將回調(diào)函數(shù)變成鏈式結(jié)構(gòu),從而解決了回調(diào)地獄的問題睹酌。
案例:
new Promise(function (resolve, reject) {
ajax({
url: '第一個請求',
success(res) {
resolve(res)
}
})
}).then(function (res) {
// 準備發(fā)送第二個請求
return new Promise(function (resolve, reject) {
ajax({
url: '第二個請求',
data: { a: res.a, b: res.b },
success(res) {
resolve(res)
}
})
})
}).then(function (res) {
ajax({
url: '第三個請求',
data: { a: res.a, b: res.b },
success(res) {
console.log(res)
}
})
}).catch(function (res) {
})
then和catch不會同時觸發(fā)权谁,也就是說,只要一個then出錯了憋沿,執(zhí)行最底下的catch就行旺芽,所以也就可以連續(xù)寫多個then,一個catch就行
終極解決方案:es7提供的async/await
可以將異步代碼寫的和同步代碼一樣
語法:
asyncfunctionfn() {
constres=awaitpromise對象
}
只要是一個 promiser 對象辐啄,那么我們就可以使用 async/await 來書寫
案例
async function fn() {
const res = new Promise(function (resolve, reject) {
ajax({
url: '第一個地址',
success(res) {
resolve(res)
}
})
})
// res 就可以得到請求的結(jié)果
const res2 = new Promise(function (resolve, reject) {
ajax({
url: '第二個地址',
data: { a: res.a, b: res.b },
success(res) {
resolve(res)
}
})
})
const res3 = new Promise(function (resolve, reject) {
ajax({
url: '第三個地址',
data: { a: res2.a, b: res2.b },
success(res) {
resolve(res)
}
})
})
// res3 就是我們要的結(jié)果
console.log(res3)
}
跨域
原因是瀏覽器的同源策略
跨域:前端是不能跨域的采章,但是后端的語言可以。
概念:瀏覽器有同源策略壶辜,禁止ajax從一個域名請求另外一個域名上的數(shù)據(jù)悯舟,如果從一個域名請求另外一個域名上的數(shù)據(jù),就是跨域
那什么是同源策略砸民,所謂同源图谷,就是指域名、協(xié)議阱洪、端口都相同。比如說:一個瀏覽器打開百度的網(wǎng)站菠镇,然后在控制臺請求騰訊的網(wǎng)頁冗荸,瀏覽器會報一個不是同源的異常。
解決:
- 1.php解決跨域:
也就是說跨域請求只是限制客戶端向服務(wù)端利耍,如果是服務(wù)端向服務(wù)端請求的話就不存在這個問題蚌本,也就是說需要跨域的請求交給php服務(wù)端來做,有了結(jié)果再響應(yīng)給ajax即可隘梨。
原理上利用的php的爬蟲技術(shù)程癌。有file_get_contents()、curl轴猎、ob_get_contents()
在服務(wù)端設(shè)置響應(yīng)頭嵌莉,允許跨域請求
如果請求的服務(wù)端是自己可操作的話,可以在php端設(shè)置允許跨域的響應(yīng)頭捻脖。代碼如下:header("Access-Control-Allow-Origin:*");
- 2.配置nginx代理:
location = 自定義url {
proxy_pass 待跨域請求的地址
}
- 3.通過jsonp來實現(xiàn):
利用標簽可以跨域(當(dāng)前網(wǎng)頁的圖片鏈接可以是別的網(wǎng)站上的圖片)的特性锐峭,制作標簽進行跨域
var script = document.createElement('script');
script.setAttribute('src', "http://www.php.com/test.php?callback=response");
$('head').append(script);
function response(res) {
$('#result').text(res);
}
// php代碼:
$fun = $_GET['callback'];
echo "$fun(".$str.")";