JS手写Promise以及promise.all方法
Promise是处理异步的一种方式,解决了回调地狱的问题。
Promise有三种状态:
1.pending(待定):初始状态。
2.fulfilled(已兑现):表示异步操作成功,返回一个返回值。
3.rejected(已拒绝):表示异步操作失败,返回一个错误原因。
状态转换:可以从pending转换到fulfiied,从pending转换到rejected。一旦转换成功,状态就不可再发生改变。
常用方法:
1.Promise.resolve():将给定的一个值转换为Promise。如果本身就是Promise,那么直接返回,如果该值是一个thenable对象,那么将调用其then方法及其两个回调函数;
2.Promise.reject():返回一个已拒绝(rejected) 的Promise对象,拒绝原因为给定的参数。
3.Promise.all():接受一个Promise可迭代对象作为输入,并返回一个Promise。当所有的Promise都被兑现时,返回的Promise也将被兑现,并返回一个包含所有兑现值的数组。输入的任何被拒绝,返回的也将被拒绝。
接下来就是基本结构:
class myPromise{
constructor(executer) {
this.state = 'pending' //初始状态为pending
this.value = undefined //成功的值
this.reason = undefined //失败原因
this.onFulfilledCallbacks = []; //成功回调函数数组
this.onRejectedCallbacks = [] //失败回调函数数组
const resolve = value => { //resolve函数,用于改变状态,从pending到fulfilled,并记录成功的值
if(this.state === 'pending') { //只有在pending状态下才能进行状态转变
this.state = 'fulfilled'
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn()) //执行每一个回调函数
}
}
const reject = reason => { //reject函数,用于改变状态
if(this.state = 'pending') { //严谨一点
this.state = 'rejected'
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn()) //执行每一个失败回调函数
}
};
try {
executor(resolve,reject);
} catch (err){
reject(err)
}
}
}
.then方法
myPromise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value //设置默认回调函数,确保函数类型,如果没有则使用默认处理函数
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
let promise2 = new myPromise((resolve,reject) => { //创建新的promise用于链式调用
if(this.state === 'fulfilled' || this.state === 'rejected') { //判断状态,如果为fulfilled,执行成功回调,反之则执行失败回调
setTimeout(() => {
try { //获取成功回调的返回值
let result = this.state ==='fulfilled' ? onFulfilled(this.value) :onRejected(this.reason)
resolvePromise(promise2, result, resolve, reject) //处理返回值确定promise2的状态
} catch (e) {
reject(e) //如果执行过程出错就reject
}
}, 0)
}
if(this.state === 'pending') { //如果状态为pending,把回调函数存储起来
this.onFulfilledCallbacks.push(()=> {
setTimeout(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
},0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
},0)
})
}
return promise2
})
}
resolvePromise方法,用于处理then方法中返回的结果,以界定新的promise状态
function resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x) { //如果一样,抛出TypeError防止自循环
return reject(new TypeError('changing cycle detected from promise'))
}
let called //如果X是对象或者数组
if(x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then //取出x的then方法
if(typeof then === 'function') { //如果then是函数,调用,传入resolvePromise和reject函数
then.call(x,y => {
if(called) return
called = true
resolvePromise(promise2, y, resolve, reject)
}, r=> {
if(called) return
called = true
reject(r)
})
} else {
reslove(x) //如果x不是,以x为值fulfill promise2
}
} catch(e) {
if(called) return
called = true
reject(e)
}
} else {
resolve(x)
}
}
resolve,reject方法用于快速生成一个promise对象
myPromise.prototype.resolve = function(value) {
return new myPromise((resolve,reject) => {
resolve(value)
})
}
myPromise.prototype.reject = function(reason) {
return new myPromise((resolve,reject) => {
reject(reason)
})
}
.all()方法,传入数组promise,将多个promise包装成一个新的promise,且只有多个全部成功,新实例才会成功
myPromise.prototype.all = function(promises) {
return new myPromise((resolve, reject) => { //返回一个新的promise
let result = [] //存储每一个promise的结果
let count = 0 //记录完成的数量
function processresult(index, data) { //处理单个promise
result[index] = data
count++
if(count === promises.length) { //如果所有promise全部完成,resolve一个新的promise
resolve(result)
}
}
for(let i=0;i<promises.length;i++) { //遍历数组,处理结果
promises[i].then(data => {
processresult(i,data)
}, reject)
}
})
}
原文地址:https://blog.csdn.net/2301_80659102/article/details/142498565
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!