基本概念
個人理解就是使用同步程式設計的寫法完成非同步程式設計操作。
const promise = new Promise((resolve, reject) => {
//some asynchronous code
setTimeout(() => {
console.log('執行完成');
resolve('some data');
}, 2000);
});
複製程式碼
Promise
接收一個函式作為引數,函式有兩個引數,resolve
和 reject
分別表示非同步操作執行後成功的回撥函式和失敗的回撥函式。
Promise
例項後馬上執行。所以通常採用一個函式包含它
function runAsync() {
return new Promise((resolve, reject) => {
//some asynchronous code
setTimeout(() => {
console.log('執行完成');
resolve('some data');
}, 2000);
});
}
runAsync().then((data) => {
console.log(data);//可以使用非同步操作中的資料
})
複製程式碼
runAsync()
執行完呼叫 then
方法,then()
就相當於我們之前寫的回撥函式。
resolve 和 reject
function paramTest(){
return new Promise((resolve, reject) => {
let number = Math.ceil(Math.random() * 10);
if (number < 5) {
resolve(number);
}else{
reject('out of range');
}
})
}
paramTest().then((number) => {
console.log('resolved');
console.log(number);
},(reason) => {
console.log('rejected');
console.log(reason);
})
複製程式碼
Promise
有三種狀態:pending
(進行中)、fulfilled
(已成功)和 rejected
(已失敗)
paramTest()
例子有兩種情況:
- 當
number < 5
時,我們認為是成功情況,將狀態從pending
變為fulfilled
- 當
number >= 5
時,我們認為是失敗情況,將狀態從pending
變為rejected
所以
paramTest()
的執行結果:
fulfilled | rejected |
---|---|
resolved | rejected |
number | out of range |
catch的用法
我們繼續呼叫
paramTest
方法舉例
paramTest().then((number) => {
console.log('resolved');
console.log(number);
console.log(data); //data為未定義
},(reason) => {
console.log('rejected');
console.log(reason);
}).catch((err) => {
console.log(err);
})
複製程式碼
catch
方法其實就是 .then(null, rejection)
的別名,也是用來處理失敗失敗的回撥函式,但是還有一個作用:當 resolve
回撥中如果出現錯誤了,不會堵塞,會執行 catch
中的回撥。
all的用法
const p = Promise.all([p1, p2, p3]);
p.then(result => {
console.log(result);
})
複製程式碼
all
方法接收一個陣列引數,陣列中每一項返回的都是Promise
物件,只有當p1, p2, p3
都執行完才會進入then
回撥。p1, p2, p3
返回的資料會以一個陣列的形式傳到then
回撥中。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p1');
}, 1000);
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2');
}, 3000);
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
//3秒後輸出['p1', 'p2']
複製程式碼
race的用法
const p = Promise.race([p1, p2, p3]);
p.then(result => {
console.log(result);
})
複製程式碼
race
的用法與all
如出一轍,不同的是all
方法需要引數的每一項都返回成功了才會執行then
;而race
則是隻要引數中的某一項返回成功就執行then
回撥。
以下是
race
的例子,和all
方法對比,可以看到返回值有很明顯的區別。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p1');
}, 1000);
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2');
}, 3000);
})
.then(result => result)
.catch(e => e);
Promise.race([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
//1秒後輸出 'p1'
複製程式碼
點選這裡檢視本文中例項原始碼
我的實踐
resloader是基於Promise實現的一個圖片預載入並展示載入進度的外掛,猛戳這裡瞭解詳情。如果感覺還可以的話,歡迎star,也歡迎各位大佬不吝指導,感謝!
最後,感謝各位的觀看!