一、Promise對象的定義
Promise對象用來將異步操作以同步操作的流程表達出來,定義如下
let flag = true;
const hello = new Promise(function (resolve, reject) {
if (false) {//異步操作成功
resolve("success");
} else {
reject("error");
}
});
二、鏈式調用-then方法
使用then方法調用,第一個參數是成功回調,第二個參數是失敗回調,如下
hello.then(
function (value) {
console.log(value)
},
function (err) {
console.log(err)
}
);
下面我們分別定義三個方法,參數為延時執行的秒數
- chenqionghe
- get
- muslce
function chenqionghe(second) {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log("chenqionghe");
resolve();
}, second * 1000);
})
}
function get(second) {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log("get");
resolve()
}, second * 1000);
})
}
function muscle(second) {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log("muscle");
resolve();
}, second * 1000);
})
}
調用如下
chenqionghe(3)
.then(function () {
return get(2)
})
.then(function () {
return muscle(1)
});
運行輸出
chenqionghe
get
muscle
這樣就實現了鏈式的調用,相當於同步的方式執行了
如果不使用then調用,會發生什么情況?如下
chenqionghe(3);
get(2);
muscle(1);
結果如下
muscle
get
chenqionghe
我們看到chenqionghe雖然是第一個執行,卻是最后輸出內容,因為設置了3秒后執行
重點:
- Promise 對象的錯誤具有“冒泡”性質,會一直向后傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch語句捕獲。
- 一般來說,不要在then方法里面定義 Reject 狀態的回調函數(即then的第二個參數),總是使用catch方法。
三、捕獲異常-catch
chenqionghe(3)
.then(function () {
return get(2)
})
.then(function () {
throw new Error("abc");
return muscle(1)
})
.catch(function (e) {
console.log("異常:" + e.message)
})
;
輸出
chenqionghe
get
異常:abc
異常本質也是一個Promise,所以后面還可以執行then
chenqionghe(3)
.then(function () {
return get(2)
})
.then(function () {
throw new Error("abc");
return muscle(1)
})
.catch(function (e) {
console.log("異常:" + e.message)
})
.then(function () {
console.log("異常后執行")
})
;
運行輸出
chenqionghe
get
異常:abc
異常后執行
四、收尾執行-finally
就是不管怎么樣,都會執行的方法,即使是拋異常了
chenqionghe(3)
.then(function () {
return get(2)
})
.then(function () {
throw new Error("abc");
return muscle(1)
})
.catch(function (e) {
console.log("異常:" + e.message)
})
.finally(function () {
console.log("最后都會執行的方法")
})
;
執行輸出
chenqionghe
get
異常:abc
最后都會執行的方法
finally本質上也是then方法的特例
五、其他方法
all
用於將多個promise實例包裝成一個新的promise實例
const p = Promise.all([p1, p2, p3]);
- 當p1、p2、p3都執行功能,會調用p的回調函數,傳p1、p2、p3返回值的一個數組
- 當p1、p2、p3其中有一個執行reject,第一個執行reject方法的返回值會傳遞給p的回調函數
race
類似all,也將多個promise實例包裝成一個新的promise實例
不同的是,要p1、p2、p3之中有一個實例發生改變,最先改變的 Promise 實例的返回值會傳遞給p的回調函數。
resolve
將現有對象轉為 Promise 對象
Promise.resolve('foo')
// 等價於
new Promise(resolve => resolve('foo'))
reject
返回一個新的 Promise 實例,該實例的狀態為rejected
const p = Promise.reject('出錯了');
// 等同於
const p = new Promise((resolve, reject) => reject('出錯了'))