Promise基本使用
const p = new Promise((resolve, reject) => { // 1)同步执行的执行器函数
// 2) 在执行器函数中启动异步任务
setTimeout(() => {
// 3) 根据结果做不同处理
const time = Date.now()
// 3.1) 如果成功了, 调用resolve(), 指定成功的value, 变为resolved状态
if (time % 2 == 1) {
resolve('成功的数据 ' + time)
console.log('resolve()之后')
} else {// 3.2) 如果失败了, 调用reject(), 指定失败的reason, 变为rejected状态
reject('失败的数据 ' + time)
}
}, 1000);
})
// 4) 能promise指定成功或失败的回调函数来获取成功的vlaue或失败的reason
p.then(
value => {
console.log('成功', value)
},
error => {
console.log('失败', error)
}
)
Promise的API
Promise构造函数: Promise (excutor) {}
excutor函数: 同步执行 (resolve, reject) => {}
resolve函数: 内部定义成功时我们调用的函数 value => {}
reject函数: 内部定义失败时我们调用的函数 reason => {}
说明: excutor会在Promise内部立即同步回调,异步操作在执行器中执行Promise.prototype.then方法: (onResolved, onRejected) => {}
onResolved函数: 成功的回调函数 (value) => {}
onRejected函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功value的成功回调和用于得到失败reason的失败回调
返回一个新的promise对象Promise.prototype.catch方法: (onRejected) => {}
onRejected函数: 失败的回调函数 (reason) => {}
说明: then()的语法糖, 相当于: then(undefined, onRejected)Promise.resolve方法: (value) => {}
value: 成功的数据或promise对象
说明: 返回一个成功/失败的promise对象Promise.reject方法: (reason) => {}
reason: 失败的原因
说明: 返回一个失败的promise对象Promise.all方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就直接失败
7.Promise.race方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
例子
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), // 数据的顺序与promise数组顺序一致,不是按先后
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的状态?
(1)resolve(value): 如果当前是pendding就会变为resolved
(2)reject(reason): 如果当前是pendding就会变为rejected
(3)抛出异常: 如果当前是pendding就会变为rejected一个promise指定多个成功/失败回调函数, 当promise改变为对应状态时都会调用
const p = new Promise((resolve, reject) => {
// resolve(1) // pending ==> resolved
// reject(2) // pending ==> rejected
// throw 3 // 执行器中抛出异常 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状态和指定回调函数谁先谁后?
(1)都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
(2)如何先改状态再指定回调?
在执行器中直接调用resolve()/reject()
延迟更长时间才调用then()
(3)什么时候才能得到数据?
①如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
②如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
const p = new Promise((resolve, reject) => { // 同步回调
console.log('excutor()')
// 启动异步任务
setTimeout(() => {
resolve(1) // pending ==> resolved value为1
console.log('resolve()改变状态后')
// reject()
}, 1000)
})
setTimeout(() => {
p.then( // 先指定回调函数, 内部选将回调函数保存起来
value => { // 成功/失败的回调函数是异步执行的, 需要放入队列将来执行
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()改变状态后')
// reject()
}, 5000)
})
setTimeout(() => {
p.then( // 先指定回调函数, 内部选将回调函数保存起来
value => { // 成功/失败的回调函数是异步执行的, 需要放入队列将来执行
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)
// 执行任务2(同步)
console.log('执行任务2(同步)')
return 2
}).then(value => {
console.log('任务2成功的vlaue为', value)
// 执行任务3(异步)
return new Promise((resolve, reject) => {
console.log('调动任务3(异步)')
setTimeout(() => {
resolve(3)
}, 1000);
})
}).then(value => {
console.log('任务3成功的value为: ', value)
})
- 中断promise链
(1)当使用promise的then链式调用时, 在中间中断, 不再调用后面的回调函数
(2)办法: 在回调函数中返回一个pendding状态的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状态的promise ==> 中断promise链接
}).then(
value => console.log('onResolved4()', value),
reason => console.log('onRejected2()', reason)
)
文章同步我的博客