首先看一個例子:
<script>
var a = 1;
setTimeout(() => {
a = 10;
}, 2000);
console.log(a);
</script>
上面是一個異步任務,setTimeout兩秒後纔會執行,所以控制檯會打印1。要想打印10,就可以把console.log(a)放在裏面即:
<script>
var a = 1;
setTimeout(() => {
a = 10;
console.log(a);
}, 2000);
</script>
這樣依然會導致回調地獄,層層嵌套的問題,這個時候就可以用promise試試。
Promise對象 基本使用
new Promise(function(resolve, reject) {
// ... 要執行的(異步)任務
})
所以上面的代碼可以改造成
new Promise( (resolve, reject) => {
setTimeout(() => {
a = 10;
}, 2000);
} );
接下來講解幾個關鍵的知識點
Promise狀態:[[PromiseStatus]]
- pending:初始狀態,既不是成功,也不是失敗狀態
- fulfilled/resolved:意味着操作成功完成
- rejected:意味着操作失敗
Promise狀態:[[PromiseStatus]]
- resolve()函數:更改Promise對象爲成功狀態
- reject()函數:更改Promise對象爲失敗狀態
then方法
任務後續處理函數,一般情況下處理某個Promise任務完成(無論是成功還是失敗)的後續任務
.then(onFulfilled/onResolved, onRejected)
onFulfilled/onResolved:fulfilled/resolved狀態下調用
onRejected:rejected狀態下調用
懵逼了有木有,來一個例子看看
<script type="text/javascript">
var a = 1;
let p1 = new Promise( (resolve, reject) => {
// 要執行的異步任務
/**
* resolve:函數,當我們調用該函數的時候,可以把當前Promise對象的任務狀態該成resolved
* reject:函數,當我們調用該函數的時候,可以把當前Promise對象的任務狀態該成rejected
*
* 只要Promise的任務狀態發生了變化,這個Promise對象的then方法就會被執行
*/
setTimeout(() => {
a = 10;
// resolve(); //resolved
reject(); //rejected
}, 2000);
} );
p1.then( () => {
// then方法就是Promise處理完任務以後繼續執行的任務
console.log(a);
}, () => {
console.log('失敗了');
} );
</script>
關於 resolve()、reject()這兩個函數傳參還有要注意的地方
Promise值:[[PromiseValue]]
任務處理完成(成功或失敗),返回的值,通過 resolve()、reject() 函數傳入
resolve(1)、reject(1)
onFulfilled/onResolved, onRejected 函數接收
.then(val=>console.log(val), ...)
看下面的例子
<script type="text/javascript">
/**
* Promise
* 構造函數,通過Promise來構建一個異步任務處理對象
*/
new Promise( (resolve, reject) => {
/**
* resolve, reject這兩個函數是可以傳入參數的,傳入的參數將被傳遞給then中的函數進行使用
*/
setTimeout(() => {
var a = 10;
// resolve(a);
reject('出錯了');
}, 2000);
} ).then( v => {
console.log(v);
}, err => {
console.log(err);
});
</script>
控制檯會打印“出錯了”。