promise加箭頭函式處理非同步結果
Promise物件
es6中新增了promise物件,為了處理非同步訊息而生,在此之前處理非同步拿到的資料就是回撥巢狀回撥,有了Promise我們就可以在需要使用非同步處理結果的地方呼叫Promise.then(func)
Promise定義
摘自 阮一峰 ECMAScript 6 入門
所謂Promise,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。
在js中很經典的非同步就是ajax請求了,我在第一個專案當中用到ajax原生請求,處理ajax請求的結果全在回撥函式當中進行,判斷狀態碼,作出相應的處理,在不同的狀態碼下的處理又非常的多,然後就是一層層巢狀,還蠻爽的==
function getMessage(url,data) {
var request = new XMLHttpRequest();
request.open("POST", url);
request.responseType = "json";
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(data);
request.onload = function () {
if (this.status === 200 ) {
if (this.response.code === 200) {
this.response.data.forEach(function (obj) {
//此處處理拿到的資料
})
} else
//此處處理後端返回錯誤
} else
//此處處理網路請求錯誤
};
}
基本上整個模組的操作都在回撥裡面做了,因為請求的結果資料就在那裡,非同步的結果是不確定的,只能在回撥函式做各種各樣的處理。
Promise的三種狀態
一個 Promise有以下幾種狀態:
- pending: 初始狀態,不是成功或失敗狀態。
- fulfilled: 意味著操作成功完成。
- rejected: 意味著操作失敗。
描述:
Promise 物件是一個代理物件(代理一個值),被代理的值在Promise物件建立時可能是未知的。它允許你為非同步操作的成功和失敗分別繫結相應的處理方法(handlers )。 這讓非同步方法可以像同步方法那樣返回值,但並不是立即返回最終執行結果,而是一個能代表未來出現的結果的promise物件。
我們給出一個用promise物件封裝的一個ajax請求:
function getDate(url, data) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open("POST", url);
request.responseType = "json";
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(data);
request.onload = function() {
if (this.status === 200) {
resolve(this.response);
} else {
reject(this.status);
}
}
})
}
// 在需要處理資料的地方
getDate(url, data).then(function(response) {
/此處處理拿到的資料
}).catch(function(err){
//此處處理錯誤
})
上面的示例就是用Promise物件封裝了ajax請求,解決了在回撥裡面處理所有結果的尷尬。
axios請求
我們可以不用人工封裝,而是藉助已經封裝好的模組axios去請求,原理看著都一樣,甚至用起來和我們自己封裝的都一樣
function getDate(url, data) {
axios.defaults.baseURL = url;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
//此處放了一個get請求,就沒用到data
axios.get('/articles/articleList').then(function(response) {
if(response.status == 200) {
if(response.data.code == 200) {
//處理
} else {
//此處處理後端返回狀態錯誤
}
}
}).catch(function(err) {
//此處處理請求錯誤
});
}
這裡我要隆重的說一句,不管這個Promise對非同步的結果做了什麼,非同步還是非同步,你想把非同步執行的結果傳出來還是不可能,除非用generator或者async轉成同步,顯然把他轉成同步不合算。
接下來我們就用箭頭函式加promise的方法解決結果不能傳出去的問題。
箭頭函式
ES6大法的箭頭函式,說一點:箭頭函式的this。
箭頭函式的this是繫結外部環境的,咱們直接看例子
var name = "zhangchi";
var Obj = {
name: "chichi",
fun1: function(){
console.log(this.name);
},
fun2: () => {
console.log(this.name);
}
}
Obj.fun1(); // chichi
Obj.fun2(); //zhangchi
看完這個例子大致就知道,箭頭函式和普通函式的this指向是不同的,所以不要在一個類裡面用箭頭函式。
終極解決方案
var data = {}; //接收非同步返回的結果
function getDate(url, data) {
axios.defaults.baseURL = url;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.get('/articles/articleList').then((response) => {
if(response.status == 200) {
if(response.data.code == 200) {
this.data = response.data.data;
} else {
//此處處理後端返回狀態錯誤
}
}
}).catch(function(err) {
//此處處理請求錯誤
});
}