手动实现promise源码
Posted 全力以赴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手动实现promise源码相关的知识,希望对你有一定的参考价值。
promise是异步解决方案,解决回调地狱问题。promise从语法上来说是一个构造函数。从功能来说封装异步操作,并且可以获取其操作结果。
1.基本用法
const p =new Promise((resolve,reject)=>{
setTimeout(()=>{
//异步操作
resolve(value)
},100)
})
构造函数Promise的参数为一个执行器函数,执行器函数的参数为resolve与reject分别代表:第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用
2.Promise构造函数的实现
Promise对象内部含有三种状态,初始值pending 已成功 resolved 已失败 rejected
内部的状态在执行过程中,状态只能改变一次并且不可逆。
初始化 初始时候将status的状态为pending callbacks用来保存成功的与失败的回调函数
self.status =PENDING
self.data =undefined
self.callbacks =[] //每个元素结构 {onResolved(){} onRejected(){} }
function Promise(excutor){
const self =this
self.status =PENDING
self.data =undefined
self.callbacks =[] //每个元素结构 {onResolved(){} onRejected(){} }
function resolve(value){
// resolve函数的作用将promise状态变为resolved
if(self.status!==PENDING){
//如果不是pending状态直接返回
return
}
self.status =RESOLVED
self.data = value
if(self.callbacks.length>0){
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
});
},0);
}
}
function reject(reason){
if(self.status!==PENDING){
return
}
self.status =REJECTED
self.data = reason
if(self.callbacks.length>0){
setTimeout(() => {
//遍历回调队列
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
});
});
}
}
//立即同步执行ex
try{
excutor(resolve,reject)
}catch(err){
reject(err)
}
}
3.promise实例的then方法
then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。并且返回也是一个Promise对象有三种情况
- 如果回调函数返回是promise return的promise的结果就是这个promise的结果
- 如果回调函数返回不是promise return的promise就会成功 value就是返回值
- 如果抛出异常 return的promise就会失败 resaon就是error
Promise.prototype.then=function(onResolved,onRejected){
const self =this
onResolved = typeof onResolved === \'function\' ? onResolved :value =>value
onRejected = typeof onRejected === \'function\' ? onRejected :reason =>{throw reason}
//返回一个新的promise 对象
return new Promise((resolve,reject)=>{
//调用指定的回调函数处理、根据执行结果 改变return的promise状态
function handle(callback){
try{
const result =callback(self.data)
if(result instanceof Promise){
//如果回调函数返回是promise return的promise的结果就是这个promise的结果
result.then(value =>{
resolve(value)
},reason =>{
reject(reason)
})
// result.then(resolve,reject)
}else{
//如果回调函数返回不是promise return的promise就会成功 value就是返回值
resolve(result)
}
}catch(error){
//如果抛出异常 return的promise就会失败 resaon就是error
reject(error)
}
}
if(self.status === PENDING){
self.callbacks.push({
onResolved(){
handle(onResolved)
},
onRejected(){
handle(onRejected)
}
})
}else if(self.status === RESOLVED){
setTimeout(()=>{
handle(onResolved)
})
}else{
setTimeout(()=>{
handle(onRejected)
})
}
})
}
4.Promise对象的catch方法
作用来捕获发生错误的回调方法
Promise.prototype.catch=function(onRejected){
return this.then(undefined,onRejected)
}
5 Promise的resolve方法
作用是将对象变为Promise对象。如果resolve方法参数是非Promise对象直接将value传递下去,如果是Promise对象value的结果将作为Promise的结果
Promise.resolve = function(value){
return new Promise((resolve,reject)=>{
//value是promise
if(value instanceof Promise){
//使用value的结果作为promise的结果
value.then(resolve,reject)
}else{
//value不是promise
resolve(value)
}
})
}
6.Promise的reject方法
作用返回一个rejected的Promise对象
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
7.Promise的all方法
作用:执行多个Promise 并返回新的Promise实例
all方法接收一个数组参数:
- 如果Promise对象全部成功,将返回一个数组保存每个成功的Promise的返回值。
- 如果有一个Promise对象失败 新的Promise将变为失败 返回值为执行失败的Promise的返回值
Promise.all = function(promises){
//用来保存所有成功value的数组
const values =new Array(promises.length)
//用来保存成功promise的数量
let count = 0
return new Promise((resolve,reject)=>{
//获取每个promise的结果
promises.forEach((p,index)=>{
Promise.resolve(p).then(value=>{
count++
values[index] = value //保存成功的值
//如果全部成功了,将return的promise变为成功
if(count === promises.length){
resolve(values)
}
},reason =>{
reject(reason)
})
})
})
}
8.Promise的race方法
作用:返回一个新的Promise对象,最先执行完成Promise的返回值作为新的Promise对象的结果
Promise.race = function(promises){
return new Promise((resolve,reject)=>{
//获取每个promise的结果
promises.forEach((p)=>{
Promise.resolve(p).then(value=>{
resolve(value)
},reason =>{
reject(reason)
})
})
})
}
以上是关于手动实现promise源码的主要内容,如果未能解决你的问题,请参考以下文章