ES6 - Promise物件
Promise 物件用於一個非同步操作的最終完成(或失敗)及其結果值的表示。簡單點說,它就是用於處理非同步操作的,非同步處理成功了就執行成功的操作,非同步處理失敗了就捕獲錯誤或者停止後續操作。
Promise物件來說,它也有三種狀態:
1.pending
初始狀態,也稱為未定狀態,就是初始化Promise時,呼叫executor執行器函式後的狀態。
2.fulfilled
完成狀態,意味著非同步操作成功。
3.rejected
失敗狀態,意味著非同步操作失敗。
它只有兩種狀態可以轉化,即:
操作成功resolve()
pending -> fulfilled
操作失敗reject()
pending -> rejected
建立一個Promise例項:
let pro = new Promise( (resolve,reject) => {
if(成功條件){
resolve('succees data'); //resolve函式裡面的引數,是當使用鏈式操作函式then時能獲取到
}else{ // 失敗條件
reject('fail data');//reject函式裡面的引數,是當使用鏈式操作函式catch時能獲取到
}
});
例項化後的Promise物件pro可以進行鏈式呼叫,而且這個then()方法
可以接收兩個函式作為引數,一個是處理成功後的函式,一個是處理錯誤結果的函式。
//第一種寫法
pro.then((data) => {
//處理成功後的操作
}, (err) => {
//處理失敗後的操作
});
catch()方法
和then()方法一樣,都會返回一個新的Promise物件,它主要用於捕獲非同步操作時出現的異常。因此,我們通常省略then()方法的第二個引數,把錯誤處理控制權轉交給其後面的catch()函式。
let pro1 = new Promise( (resolve,reject) => {
reject('出錯了'); //人為置為失敗,返回一個rejected的Promise例項
});
pro1.then( (data) => { //因為上面人為置為失敗了,所以then不執行
console.log("這裡是非同步操作成功後執行的");
}).catch( (err) =>{
console.log("這裡是非同步操作失敗後執行的:" + err);
});
//最後輸出了:
// 這裡是非同步操作失敗後執行的:出錯了
Promise例項物件為一個函式的用法:
let ajax = (num) => {
return new Promise ( (resolve,reject) => {
if (num > 5){
resolve("大於5");
}else {
reject("不大於5");
}
})
}
//Promise物件的鏈式操作
ajax(6).then( (data) => {
console.log(data);
}).catch( (err) => {
console.log(err);
});
//最後輸出:
// 大於5
如果有若干個非同步任務,需要先做任務1,如果成功,再做任務2,如果中間任何一個任務失敗,才不繼續進行執行處理函式 。
我們需要序列執行這樣的非同步任務,就可以寫成:(其實就是在then方法中再返回一個Promise例項物件,然後後面就能繼續使用then方法進行序列執行任務了。)
let dataJson = {a:1,b:2}
let ajax = () => {
return new Promise ( (resolve,reject) => {
resolve(dataJson);
})
}
//Promise物件的鏈式操作
ajax().then( (data) => {
console.log(data);
//返回一個Promise例項,方便後面可以繼續使用鏈式操作then和catch
return new Promise( (resolve,reject) => {
resolve(22);
});
//等價於
// return Promise.resolve(22);
}).catch( (err) => {
console.log(err);
}).then( (data2) => { //因為上面又返回了Promise例項,所以還可以使用鏈式操作
console.log(data2);
});
//最後輸出:
// {a:1,b:2}
// 22
返回的這個Promise物件的狀態主要是根據Promise例項.then()方法返回的值,大致分為以下幾種情況:
1、如果then()方法中返回了一個引數值
,那麼返回的Promise將會變成接收狀態(fulfilled)。
2、如果then()方法中丟擲了一個異常
,那麼返回的Promise將會變成拒絕狀態(rejected)。
3、如果then()方法呼叫resolve()方法
,那麼返回的Promise將會變成接收狀態。
4、如果then()方法呼叫reject()方法
,那麼返回的Promise將會變成拒絕狀態。
5、如果then()方法返回了一個未知狀態(pending)的Promise新例項
,那麼返回的新Promise就是未知狀態。
6、如果then()方法沒有明確指定的resolve(data)/reject(data)/return data
時,那麼返回的新Promise就是接收狀態,可以一層一層地往下傳遞。
例子如下:
let promise2 = new Promise( (resolve, reject) => {
// 置為接收狀態
resolve('success');
});
promise2
.then((data) => {
// 上一個then()呼叫了resolve,置為接收狀態fulfilled
console.log('第一個then'); //第一個then
console.log(data); // success
return '2';
})
.then((data) => {
// 此時這裡的狀態也是fulfilled, 因為上一步返回了一個引數值2
console.log('第二個then'); //第二個then
console.log(data); // 2
// 返回一個rejected的Promise例項
return Promise.reject("把狀態置為rejected error");
}, (err) => { //then的第二個函式是捕獲錯誤而執行的
// error
})
.then((data) => {
/* 這裡不執行,因為上一步呼叫reject()方法,那麼返回的Promise將會變成拒絕狀態 */
console.log('第三個then');
console.log(data);
}, (err) => {//then的第二個函式是捕獲錯誤而執行的
// 此時這裡的狀態是rejected, 因為上一步使用了reject()來返回值
console.log('出錯:' + err); // 出錯:把狀態置為rejected error
})
.then((data) => {
// 沒有明確指定返回值,預設返回fulfilled (如果後面還有then那麼就會是接收狀態)
console.log('這裡是fulfilled態'); //這裡是fulfilled態
})
//最後輸出:
// 第一個then
// success
// 第二個then
// 2
// 出錯:把狀態置為rejected error
// 這裡是fulfilled態