Promise基本使用
const p = new Promise((resolve, reject) => { // 1)同步執(zhí)行的執(zhí)行器函數(shù)
// 2) 在執(zhí)行器函數(shù)中啟動異步任務
setTimeout(() => {
// 3) 根據(jù)結果做不同處理
const time = Date.now()
// 3.1) 如果成功了, 調用resolve(), 指定成功的value, 變?yōu)閞esolved狀態(tài)
if (time % 2 == 1) {
resolve('成功的數(shù)據(jù) ' + time)
console.log('resolve()之后')
} else {// 3.2) 如果失敗了, 調用reject(), 指定失敗的reason, 變?yōu)閞ejected狀態(tài)
reject('失敗的數(shù)據(jù) ' + time)
}
}, 1000);
})
// 4) 能promise指定成功或失敗的回調函數(shù)來獲取成功的vlaue或失敗的reason
p.then(
value => {
console.log('成功', value)
},
error => {
console.log('失敗', error)
}
)
Promise的API
Promise構造函數(shù): Promise (excutor) {}
excutor函數(shù): 同步執(zhí)行 (resolve, reject) => {}
resolve函數(shù): 內部定義成功時我們調用的函數(shù) value => {}
reject函數(shù): 內部定義失敗時我們調用的函數(shù) reason => {}
說明: excutor會在Promise內部立即同步回調,異步操作在執(zhí)行器中執(zhí)行Promise.prototype.then方法: (onResolved, onRejected) => {}
onResolved函數(shù): 成功的回調函數(shù) (value) => {}
onRejected函數(shù): 失敗的回調函數(shù) (reason) => {}
說明: 指定用于得到成功value的成功回調和用于得到失敗reason的失敗回調
返回一個新的promise對象Promise.prototype.catch方法: (onRejected) => {}
onRejected函數(shù): 失敗的回調函數(shù) (reason) => {}
說明: then()的語法糖, 相當于: then(undefined, onRejected)Promise.resolve方法: (value) => {}
value: 成功的數(shù)據(jù)或promise對象
說明: 返回一個成功/失敗的promise對象Promise.reject方法: (reason) => {}
reason: 失敗的原因
說明: 返回一個失敗的promise對象Promise.all方法: (promises) => {}
promises: 包含n個promise的數(shù)組
說明: 返回一個新的promise, 只有所有的promise都成功才成功, 只要有一個失敗了就直接失敗
7.Promise.race方法: (promises) => {}
promises: 包含n個promise的數(shù)組
說明: 返回一個新的promise, 第一個完成的promise的結果狀態(tài)就是最終的結果狀態(tài)
例子
new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(1)
reject(2)
}, 1000);
}).then(value => {
console.log('onResolved()', value)
}/* , error=> {
console.log('onRejected()', error)
} */).catch(error=> {
console.log('onRejected2()', error)
})
此法來解決回調地獄
//回調地獄
doSomething(function (result) {
// 第一個異步任務成功啟動第二個異步任務
doSomethingElse(result, function (newResult) {
// 第二個異步任務成功啟動第三個異步任務
doThirdThing(newResult, function (finalResult) {
// 第三個異步任務成功了
console.log('Got the final result: ' + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
//鏈式調用解決回調地獄
doSomething()
.then(function (result) {
return doSomethingElse(result)
})
.then(function (newResult) {
return doThirdThing(newResult)
})
.then(function (finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
Promise.all 全成功才行
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const p4 = Promise.reject(4)
p1.then(value => console.log('p1 value', value))
p2.then(value => console.log('p2 value', value))
p3.catch(reason => console.log('p3 value', reason))
p4.catch(reason => console.log('p4 value', reason))
const pa = Promise.all([p1, p2, p3, p4])
// const pa = Promise.all([p1, p2])
pa.then(
values => console.log('pa all onResolved()', values), // 數(shù)據(jù)的順序與promise數(shù)組順序一致,不是按先后
reason => console.log('pa all onRejected()', reason),
)
Promise.race 誰先取誰
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const p4 = Promise.reject(4)
p1.then(value => console.log('p1 value', value))
p2.then(value => console.log('p2 value', value))
p3.catch(reason => console.log('p3 value', reason))
p4.catch(reason => console.log('p4 value', reason))
const pr = Promise.race([p1, p3, p2])
//const pr = Promise.race([p2, p3, p1])
pr.then(
value => console.log('pr race onResolved()', value),
reason => console.log('pr race onRejected()', reason),
)
深入Promise
如何改變promise的狀態(tài)?
(1)resolve(value): 如果當前是pendding就會變?yōu)閞esolved
(2)reject(reason): 如果當前是pendding就會變?yōu)閞ejected
(3)拋出異常: 如果當前是pendding就會變?yōu)閞ejected一個promise指定多個成功/失敗回調函數(shù), 當promise改變?yōu)閷獱顟B(tài)時都會調用
const p = new Promise((resolve, reject) => {
// resolve(1) // pending ==> resolved
// reject(2) // pending ==> rejected
// throw 3 // 執(zhí)行器中拋出異常 pending ==> rejected
})
p.then(
value => console.log('onResolved()', value),
reason => console.log('onRejected()', reason)
)
p.then(
value => console.log('onResolved2()', value),
reason => console.log('onRejected2()', reason)
)
console.log(p)
- 改變promise狀態(tài)和指定回調函數(shù)誰先誰后?
(1)都有可能, 正常情況下是先指定回調再改變狀態(tài), 但也可以先改狀態(tài)再指定回調
(2)如何先改狀態(tài)再指定回調?
在執(zhí)行器中直接調用resolve()/reject()
延遲更長時間才調用then()
(3)什么時候才能得到數(shù)據(jù)?
①如果先指定的回調, 那當狀態(tài)發(fā)生改變時, 回調函數(shù)就會調用, 得到數(shù)據(jù)
②如果先改變的狀態(tài), 那當指定回調時, 回調函數(shù)就會調用, 得到數(shù)據(jù)
const p = new Promise((resolve, reject) => { // 同步回調
console.log('excutor()')
// 啟動異步任務
setTimeout(() => {
resolve(1) // pending ==> resolved value為1
console.log('resolve()改變狀態(tài)后')
// reject()
}, 1000)
})
setTimeout(() => {
p.then( // 先指定回調函數(shù), 內部選將回調函數(shù)保存起來
value => { // 成功/失敗的回調函數(shù)是異步執(zhí)行的, 需要放入隊列將來執(zhí)行
console.log('onResolved()', value)
}
)
},5000);
console.log('new Promise()之后')
const p = new Promise((resolve, reject) => { // 同步回調
console.log('excutor()')
// 啟動異步任務
setTimeout(() => {
resolve(1) // pending ==> resolved value為1
console.log('resolve()改變狀態(tài)后')
// reject()
}, 5000)
})
setTimeout(() => {
p.then( // 先指定回調函數(shù), 內部選將回調函數(shù)保存起來
value => { // 成功/失敗的回調函數(shù)是異步執(zhí)行的, 需要放入隊列將來執(zhí)行
console.log('onResolved()', value)
}
)
},1000);
console.log('new Promise()之后')
- promise的then()返回一個新的promise, 可以開成then()的鏈式調用,通過then的鏈式調用串連多個同步/異步任務
new Promise((resolve, reject) => {
// 啟動任務1(異步)
console.log('啟動任務1(異步)')
setTimeout(() => {
resolve(1)
}, 1000)
}).then(value => {
console.log('任務1成功的value為', value)
// 執(zhí)行任務2(同步)
console.log('執(zhí)行任務2(同步)')
return 2
}).then(value => {
console.log('任務2成功的vlaue為', value)
// 執(zhí)行任務3(異步)
return new Promise((resolve, reject) => {
console.log('調動任務3(異步)')
setTimeout(() => {
resolve(3)
}, 1000);
})
}).then(value => {
console.log('任務3成功的value為: ', value)
})
- 中斷promise鏈
(1)當使用promise的then鏈式調用時, 在中間中斷, 不再調用后面的回調函數(shù)
(2)辦法: 在回調函數(shù)中返回一個pendding狀態(tài)的promise對象
new Promise((resolve, reject) => {
// resolve(1)
reject(2)
}).then(
value => console.log('onResolved1()', value),
// reason => {throw reason}
).then(
value => console.log('onResolved2()', value),
// reason => Promise.reject(reason)
).then(
value => console.log('onResolved3()', value),
// reason => {throw reason}
).catch(reason => {
console.log('onRejected1()', reason)
// throw reason
return new Promise(() => {}) // 返回一個pending狀態(tài)的promise ==> 中斷promise鏈接
}).then(
value => console.log('onResolved4()', value),
reason => console.log('onRejected2()', reason)
)
文章同步我的博客