ES6-Promise及源码实现
开头说明promise实例化对象的属性值 [promiseState]promise实例化对象的属性值 [promiseResult]promise的APIPromise的构造函数 [Promise(executor){}]Promise.prototype.then方法 [(onResolved, onRejected){}]Promise.prototype.catch方法 [(onRejec
- 开头说明
- promise实例化对象的属性值 [promiseState]
- promise实例化对象的属性值 [promiseResult]
- promise的API
- Promise的构造函数 [Promise(executor){}]
- Promise.prototype.then方法 [(onResolved, onRejected){}]
- Promise.prototype.catch方法 [(onRejected){}]
- Promise.resolve方法 属于Promise函数对象 [(value) => {}]
- Promise.reject方法 属于Promise函数对象 [(reason) => {}]
- Promise.all方法 属于Promise函数对象 [(promises) => {}]
- Promise.race方法 属于Promise函数对象 [(promises) => {}]
- Promise的关键问题
- 根据Promise/A+规范实现Promise
开头说明
文档最后有完整的依照Promise/A+
规范手写的Promise
代码
promise实例化对象的属性值 [promiseState]
pending
等待resolve
/fullfilled
成功reject
失败
promise实例化对象的属性值 [promiseResult]
- 保存着异步操作 [成功/失败] 返回的值
- 只有
resolve
和reject
这两个函数可以修改这个值
promise的API
Promise的构造函数 [Promise(executor){}]
executor
函数:执行器函数 形如(resolve, reject) => {}
resolve
函数:执行器函数内部成功以后执行的函数reject
函数:执行器函数内部失败以后执行的函数
执行器函数
executor
的内容会在Promise的内部同步调用
Promise.prototype.then方法 [(onResolved, onRejected){}]
onResolved
函数:Promise对象的状态变成resolve
的时候,执行的回调函数(value) => {...}
onRejected
函数:Promise对象的状态变成reject
的时候,执行的回调函数(reason) => {...}
value
和reason
是执行resolve
和reject
函数返回的值
then
方法会重新返回一个新的Promise
对象
Promise.prototype.catch方法 [(onRejected){}]
onRejected
函数:Promise对象的状态变成reject
的时候,执行的回调函数(reason) => {...}
Promise.resolve方法 属于Promise函数对象 [(value) => {}]
- value是传入的值 不同的value会导致返回的Promise对象的状态不一致
如果value是非Promise的实例化对象 那么返回
resolve
状态的Promise对象 返回值是value
如果value是Promise的实例化对象 返回状态和返回值由传入的Promise的实例化对象决定
Promise.resolve(111)
/* promiseState='resolve' promiseResult=111 */
Promise.resolve(true)
/* promiseState='resolve' promiseResult=true */
Promise.resolve(new Promise(resolve,reject) => {
resolve('OK')
/* promiseState='resolve' promiseResult='OK' */
reject('Error')
/* promiseState='reject' promiseResult='Error' */
})
Promise.reject方法 属于Promise函数对象 [(reason) => {}]
- reason是传入的值 无论传入什么值 最后都会返回一个状态为
reject
的Promise对象
执行该函数得到的Promise对象需要调用catch函数 否则浏览器会报错
Promise.resolve(111)
/* promiseState='reject' promiseResult=111 */
Promise.resolve(true)
/* promiseState='reject' promiseResult=true */
const myPromise = Promise.resolve(new Promise(resolve,reject) => {
resolve('OK')
/* promiseState = 'reject' promiseResult = new Promise(...)
返回的Promise对象的状态为resolve */
reject('Error')
/* promiseState = 'reject' promiseResult = new Promise(...)
返回的Promise对象的状态为reject */
})
myPromise.catch((reason) => {
console.log(reason)
})
Promise.all方法 属于Promise函数对象 [(promises) => {}]
- promises是promise对象构成的数组 返回一个新的Promise对象
如果promises中所有的Promise对象的状态都为
resolve
那么返回的Promise的状态为resolve
值为promises中所有
成功对象的返回值
如果promises中有一个对象的状态为reject
那么返回的Promise的状态为reject
值为promises中第一个
失败对象的返回值
Promise.race方法 属于Promise函数对象 [(promises) => {}]
promises
是Promise对象构成的数组 返回一个新的Promise对象
返回的Promise对象的状态由
promises
数组中第一个完成状态修改的对象决定(setTimeout
会影响最后的结果)
Promise的关键问题
Promise对象状态的修改
resolve
函数可以使promiseStatus
的状态变成resolve
reject
函数和throw
操作可以使promiseStatus
的状态变成rejected
Promise对象执行多个回调函数
let p = new Promise((resolve,reject) => {
resolve('OK');
})
p.then(value => {
console.log(value)
})
p.then(value => {
alert(value)
})
可以为
Promise
对象指定多个回调函数(then
)会按定义的先后去执行
Promise状态改变和回调函数执行的先后顺序
- 情况1 同步操作
let p = new Promise((resolve,reject) => {
resolve('OK');
})
p.then(value => {
console.log(value)
})
这种情况下 因为
exector
执行函数是同步调用的resolve
函数也是 所以先执行状态改变的函数 再去执行then
回调函数
- 情况2 异步操作 实际开发中占绝大部分
let p = new Promise((resolve,reject) => {
// 使用延时函数模拟接口调用的过程
setTimeout(() => {
resolve('OK');
},1000)
})
p.then(value => {
console.log(value)
})
这种情况下
resolve
函数延迟了一秒钟才执行 所以回调函数then
会先执行 等promiseStatus
的值改变后 再去调用成功的回调函数
Promise的回调函数then的返回结果
promise
对象的回调函数then
返回的也是一个promise
对象promiseStatus
和promiseResult
的返回值规则和Promise.resolve()
一致
Promise对象的链式调用
- 因为
promise
对象的回调函数then
返回的也是一个promise
对象 所以支持链式调用
Promise的异常穿透
let p = new Promise((resolve,reject) => {
// resolve('OK)
// throw 'ERR'
}).then(value => {
console.log(111)
}).then(value => {
console.log(2222)
}).then(value =>{
console.log(33333)
}).catch(reason => {
console.log(reason)
})
在使用
Promise
进行链式调用的时候,不需要为每一个then
回调函数指定错误的回调函数
只需要在最后加上catch
回调 只要链式调用过程中promiseResult
的状态变成了rejected
就会执行catch
操作
Promise的终止操作
- 因为
then
函数的特性 返回的promise
对象的promiseStatus
的值决定着后续的操作 - 所以 有且只有一种方式终止操作 返回一个
pending
状态的promise
对象 - 返回
ture null
之类的都是resolve
状态throw
操作会被catch
捕获
let p = new Promise((resolve,reject) => {
resolve('Ok')
}).then(value => {
console.log(111);
return new Promise(() => {});//pending状态的promise对象
}).then(value => {
console.log(2222)
}).then(value =>{
console.log(33333)
}).catch(reason => {
console.log(reason)
})
// 上述代码只会打印出111
根据Promise/A+规范实现Promise
function Promise(executor) {
this.PromiseStatus = 'pending';
this.PromiseResult = 'null';
this.resolveCallbacks = [];
this.rejectCallbacks = [];
/**如果不定义的话 resolve和reject函数的this指向window 无法修改状态和返回值 */
const self = this
function resolve(data) {
if(self.PromiseStatus !== 'pending') return ;
self.PromiseStatus = 'resolved';
self.PromiseResult = data;
/**处理异步操作 可以有多个回调函数 */
self.resolveCallbacks.forEach(onResolved => {
onResolved(self.PromiseResult)
})
}
function reject(data) {
if(self.PromiseStatus !== 'pending') return ;
self.PromiseStatus = 'rejected';
self.PromiseResult = data;
/**处理异步操作 可以有多个回调函数 */
self.rejectCallbacks.forEach(onRejected => {
onRejected(self.PromiseResult)
})
}
try{
/**resolve 和 reject是实参 */
executor(resolve, reject);
}catch(e){
/**处理throw 抛出异常的情况 */
reject(e);
}
}
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
/**返回值必须是promise对象 */
return new Promise((resolve,reject) => {
/**判断用户是否传参 如果不传回调函数的话 默认补上 */
if(typeof onRejected !== 'function'){
onRejected = (reason) => {
throw reason
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value
}
/**封装处理函数 */
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
/*
** 调用then方法 来判断返回的promise的状态是成功还是失败
** 如果result没有改变自己的状态 那么就返回pending状态 改变了就会走then方法
*/
result.then(value => {
resolve(value);
}, reason => {
reject(reason);
})
}else{
resolve(result);
}
}catch(e){
/**处理throw操作 */
reject(e)
}
}
/**根据PromiseStatus的值调用对应的回调函数 */
/**处理同步的情况 */
if(this.PromiseStatus === 'resolved'){
callback(onResolved);
}
if(this.PromiseStatus === 'rejected'){
callback(onRejected);
}
/**处理异步的情况 then方法执行的时候 promise对象的状态还未改变 */
if(this.PromiseStatus === 'pending'){
/*
** 保存成功和失败的回调函数供Promise构造函数中的resolve和reject调用
** 需要考虑到多个then回调函数的情况
*/
this.resolveCallbacks.push(function(){
callback(onResolved);
});
this.rejectCallbacks.push(function(){
callback(onRejected);
});
}
})
}
Promise.prototype.catch = function(onRejected) {
return this.then(undefined,onRejected);
}
更多推荐
所有评论(0)