2、promise物件
js單執行緒非同步執行的特性,因此在程式碼中充斥著回撥函式。隨著回撥函式的增加,程式碼的可讀性會愈來愈差,因此引入promise物件是不錯的一種選擇,可以避免層層回撥函式。在ECMA6中提供了原生的promise物件而不再需要第三庫。
2.1 promise構造
ECMA6中所提供的promise物件是由建構函式生成的,基本用法如下:
程式碼 2.1.1
new Promise(function (resolver, reject) {
if (success)
resolver(data)
else
reject(error)
});
在promise的建構函式中接受(一個帶有兩個引數的)函式做為入參,兩個引數分別是resolver和reject,用於在非同步回撥中將狀態改為成功,或將狀態改為失敗。程式碼2.1.2展示promise的簡單示例:
var getData = function (data) {
return new Promise(function (resolver, reject) {
if (data === -1)
reject(data);
setTimeout(resolver([1, 2, 3, 4, 5]), 1);
})
}
getdata是一個返回promise物件的函式,通過setTimeout來模擬非同步操作,當操作成功返回陣列[],當輸入引數為-1時返回失敗狀態。程式碼2.1.3呼叫getdata函式並返回結果,通過then方法得到成功後回撥,而通過catch指定失敗後的回撥,除了通過catch方法指定失敗回撥外,還可以通過then方法的第二引數指定失敗回撥,兩種方式等價。
getData(1).then(function (data) {
console.log(data);
}).catch(function (data) {
console.log('出現異常:'+data);
})
====
[ -1, 2, 3, 4, 5 ]
2.2、promise.all
很多業務場景需要對資料進行集合操作,例如傳送資料取出一個集合資料,遍歷集合資料將集合資料又傳送至另一個介面取資料,這是一個典型的二次呼叫介面方法,此時就需要使用到promise.all 方法。
// return 集合
var getData = function (data) {
return new Promise(function (resolver, reject) {
if (data === -1)
reject(data);
setTimeout(resolver([-1, 2, 3, 4, 5]), 1);
})
}
var getdataInfo = function (data) {
return new Promise(function (resolver, reject) {
if (data === -1)
reject(data);
console.log(data + '的詳情是...');
setTimeout(resolver(data), 1);
})
}
getData(1).then(function (data) {
var array = data.map(getdataInfo);
Promise.all(array).then(function (data) {
console.log('全部請求成功');
}).catch(function (data) {
console.log('資料' + data + '失敗');
});
})
getdata函式返回一個集合,集合中的資料作為getdatainfo的函式的引數,而datainfo函式也是一個非同步操作,首先通過陣列map方法生成promise物件的陣列,然後呼叫promise.all(array)呼叫promise陣列,當整個promise都返回時觸發promise.all的then方法,當其中一個失敗的時候觸發catch方法。