基本概念
個人理解就是使用同步編程的寫法完成異步編程操作幢哨。
const promise = new Promise((resolve, reject) => {
//some asynchronous code
setTimeout(() => {
console.log('執(zhí)行完成');
resolve('some data');
}, 2000);
});
Promise
接收一個函數(shù)作為參數(shù)赡勘,函數(shù)有兩個參數(shù),resolve
和 reject
分別表示異步操作執(zhí)行后成功的回調(diào)函數(shù)和失敗的回調(diào)函數(shù)捞镰。
Promise
實例后馬上執(zhí)行闸与。所以通常采用一個函數(shù)包含它
function runAsync() {
return new Promise((resolve, reject) => {
//some asynchronous code
setTimeout(() => {
console.log('執(zhí)行完成');
resolve('some data');
}, 2000);
});
}
runAsync().then((data) => {
console.log(data);//可以使用異步操作中的數(shù)據(jù)
})
runAsync()
執(zhí)行完調(diào)用 then
方法,then()
就相當于我們之前寫的回調(diào)函數(shù)岸售。
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
有三種狀態(tài):pending
(進行中)几迄、fulfilled
(已成功)和 rejected
(已失敗)
paramTest()
例子有兩種情況:
- 當
number < 5
時冰评,我們認為是成功情況映胁,將狀態(tài)從pending
變?yōu)?fulfilled
- 當
number >= 5
時,我們認為是失敗情況甲雅,將狀態(tài)從pending
變?yōu)?rejected
所以
paramTest()
的執(zhí)行結(jié)果:
fulfilled | rejected |
---|---|
resolved | rejected |
number | out of range |
catch的用法
我們繼續(xù)調(diào)用
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)
的別名解孙,也是用來處理失敗失敗的回調(diào)函數(shù),但是還有一個作用:當 resolve
回調(diào)中如果出現(xiàn)錯誤了抛人,不會堵塞弛姜,會執(zhí)行 catch
中的回調(diào)。
all的用法
const p = Promise.all([p1, p2, p3]);
p.then(result => {
console.log(result);
})
all
方法接收一個數(shù)組參數(shù)妖枚,數(shù)組中每一項返回的都是Promise
對象廷臼,只有當p1, p2, p3
都執(zhí)行完才會進入then
回調(diào)。p1, p2, p3
返回的數(shù)據(jù)會以一個數(shù)組的形式傳到then
回調(diào)中。
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
方法需要參數(shù)的每一項都返回成功了才會執(zhí)行then
;而race
則是只要參數(shù)中的某一項返回成功就執(zhí)行then
回調(diào)寂恬。
以下是
race
的例子,和all
方法對比莱没,可以看到返回值有很明顯的區(qū)別初肉。
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實現(xiàn)的一個圖片預(yù)加載并展示加載進度的插件,猛戳這里了解詳情饰躲。如果感覺還可以的話牙咏,歡迎star