PromiseA+规范
规范:
1. promise三种状态
一个promise可能有三种状态:等待(pending)、已完成(fulfilled / resolved)、已拒绝(rejected)
2. 状态转换:
pending ====> fulfilled / resolved
pending ====> rejected
> 说明:
> 只有这两种转换状态,且一个promise对象只能改变一次状态。
- 如何改变promise的状态?
(1). resolve(value): 如果当前是pending就会变为fulfilled
(2). reject(reason): 如果当前是pending就会变为rejected
(3). 抛出异常: 如果当前是pending就会变为rejected
3. promise基本运行流程
<script>
//1.创建一个新的promise对象
let p = new Promise((resolve,reject)=>{//执行器函数 同步回调函数
//2.执行异步操作
setTimeout(()=>{
const time = Date.now();
//假设时间为偶数时成功,奇数时失败
if(time%2 === 0){
//3.1如果成功了,调用resolve(value)
resolve("成功");
}else{
//3.2如果失败了,调用reject(reason)
reject("失败");
}
},1000);
});
p.then(
//成功异步回调函数
//onFulfilled
value => {//接受得到成功的value数据
console.log("成功的回调:",value);//成功的回调: 成功
},
//失败异步回调函数
//onRejected
reason => {//接受得到失败的reason数据
console.log("失败的回调:",reason);//失败的回调:失败
}
)
</script>
4. 一个promise指定多个成功/失败回调函数, 都会调用吗?
- 答:当promise改变为对应状态时都会调用
let p = new Promise((resolve, reject) => { throw new Error('Promise状态会被标记为rejected') }); p.then( value => { console.log('value1', value) }, reason => { console.log('reason1', reason) } ) p.then( value => { console.log('value2', value) }, reason => { console.log('reason2', reason) } ) /* *执行结果: *reason1,Promise状态会被标记为rejected *reason2,Promise状态会被标记为rejected */
5. promise.then()
promise应该提供一个then方法, 用来访问最终的结果, 无论是value还是reason.
promise.then()返回一个新的promise对象,新的promise对象的结果状态由then()的回调函数返回的结果决定
promise2 = promise1.then(onFulfilled, onRejected);
假设onFulfilled 或 onRejected 执行结果(返回值)为x,调用 resolvePromise(),可得出promise2的结果状态
6. resolvePromise()
resolvePromise(promise2, x, resolve, reject)
-
如果 promise2 和 x 相等,即.then() 或 .catch() 的onFulfilled/onRejected返回的值不能是 promise 本身,否则会造成死循环
const promise = Promise.resolve().then(() => { return promise // X }) // TypeError: Chaining cycle detected for promise #<Promise>
-
如果 x 是一个 promise
如果x是pending态,那么必须要停在pending,直到 x 变成 fulfilled or rejected.【中断promise链】new Promise((resolve, reject) => { reject(1) }).then( value => { console.log('onResolved3()', value) }, reason => Promise.reject(reason) ).catch(reason => { console.log('onReejected1()', reason) return new Promise(()=>{}) // 返回一个pending的promise 中断promise链 }).then( value => { console.log('onResolved3()', value) }, reason => { console.log('onReejected2()', reason) } ) /* *执行结果: *onReejected1() 1 */
如果 x 变成fulfilled/rejected状态, 那么X的执行结果就会成为then()返回结果
new Promise((resolve, reject) => { reject(1) }).then( value => { console.log('onResolved1()', value) }, reason => { console.log('onRejected1()', reason) return Promise.resolve(3) // return Promise.reject(4) } ).then( value => { console.log('onResolved2()', value) }, reason => { console.log('onRejected2()', reason) } )
-
如果 x 是一个 object 或者 是一个 function
let then = x.then.
如果 x.then 这步出错,那么 reject
如果 then 是一个函数,then.call(x, resolvePromiseFn, rejectPromise)
resolvePromiseFn 的 入参是 y, 执行 resolvePromise(promise2, y, resolve, reject);
rejectPromise 的 入参是 r, reject promise with r.
如果 then 不是一个function. fulfill promise with x.
7. 注意点
-
promise如何串连多个操作任务?
(1). promise的then()返回一个新的promise对象,可以看成then()的链式调用
(2). 通过then的链式调用串连多个同步/异步任务
(3). 链式调用中,只有前一个 then 的回调执行完毕后,跟着的 then 中的回调才会被加入至微任务队列。 -
promise异常传透?
当使用promise的then链式调用时, 可以在最后指定失败的回调,前面任何操作出了异常, 都会传到最后失败的回调中处理
语法:
1. Promise构造函数: Promise (excutor) {}
excutor函数: (resolve, reject) => {} // 同步执行
说明: excutor会在Promise内部立即同步回调,异步操作在执行器(excutor函数)中执行
resolve函数: 内部定义成功时我们调用的函数
* (value) => {}
reject函数: 内部定义失败时我们调用的函数
* (reason) => {}
2. then方法: (onFulfilled, onRejected) => {}
Promise提供一个then方法, 用来访问最终的结果, 无论是value还是reason
onFulfilled函数: 成功的回调函数
* (value) => {}
onRejected函数: 失败的回调函数
* (reason) => {}
说明: 指定用于得到成功value的成功回调和用于得到失败reason的失败回调,返回一个新的promise对象,then() 中的参数必须是函数,如果是非函数,则会发生值穿透,且为同步执行
setTimeout(() => {
console.log(1);
},0);
new Promise(function(resolve){
resolve();
console.log(2);
}).then(console.log(3))
console.log(4);
/*
执行结果:
2
3
4
1
*/
3. catch方法: (onRejected) => {}
onRejected函数: 失败的回调函数
* (reason) => {}
说明: then()的语法糖, 相当于: then(undefined, onRejected)
4. Promise.resolve(value) => {}
value: 成功的数据或promise对象
说明: 返回一个状态由给定value决定的Promise对象。
5. Promise.reject(reason) => {}
reason: 失败的原因
说明: 返回一个失败的promise对象
6. Promise.all(promises) => {}
promises:一个promise数组,数组中的元素可以是promise,可以不是promise
说明: 在数组中所有promise执行完毕后返回结果,结果是一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就失败
7. Promise.race(promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
// 产生一个成功或者失败的 Promise
let p1 = new Promise((resolve, reject) => {
// 下面两个方法只能执行一个,因为状态只能改变一次
resolve('成功了执行resolve(),Promise状态变为resolved')
//reject('失败执行reject(),Promise状态变为rejected')
});
/*
let p = new Promise((resolve, reject) => {
resolve('成功')
});
语法糖形式:
let p = Promise.resolve('成功')
*/
let p2 = Promise.resolve(`成功了执行resolve(),Promise状态变为resolved`);
let p3 = Promise.reject('失败了执行reject(),Promise状态变为rejected');
p1.then(value => {// 执行 onFulfilled()回调函数
console.log(value)
})
p2.then(value => { // 执行 onFulfilled()回调函数
console.log(value)
})
p3.then(null, reason => { // 执行onRejected()回调函数
console.log(reason)
})
p3.catch(reason => { // 执行onRejected()回调函数
console.log(reason)
})
// 所有的成功才算成功,只要有一个失败就失败
const promise = Promise.all([p1, p2, p3]);
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
// 谁先执行完就返回谁
const rece = Promise.race([p1, p2, p3]);
rece.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})