当前位置:网站首页>手写promise
手写promise
2022-07-31 08:11:00 【扣1送地狱火】
整体框架搭建
/**
* 自定义Promise函数模块:IIFE
*/
(function (window) {
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
/**
* Promise构造函数
* @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
*/
function Promise(executor) {
}
/**
* Promise原型对象then方法
* 指定成功和失败的回调函数
* @param {function} onResolved 成功的回调函数(value) => {}
* @param {function} onRejected 失败的回调函数(reason) => {}
* @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
*/
Promise.prototype.then = function (onResolved, onRejected) {
}
/**
* Promise原型对象catch方法
* 指定失败的回调函数
* @param {function} onRejected 失败的回调函数(reason) => {}
* @returns 一个新的promise对象
*/
Promise.prototype.catch = function (onRejected) {
}
/**
* Promise函数对象resolve方法
* @param {*} value 成功的值
* @returns 一个成功/失败的promise
*/
Promise.resolve = function (value) {
}
/**
* Promise函数对象reject方法
* @param {*} resaon 失败的原因
* @returns 一个失败的promise
*/
Promise.reject = function (resaon) {
}
/**
* Promise函数对象all方法
* @param {Array<Promise>} promises
* @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
*/
Promise.all = function (promises) {
}
/**
*Promise函数对象race方法
* @param {Array<Promise>} promises
* @returns 返回 一个promise,其结果由第一个完成的promise决定
*/
Promise.race = function (promises) {
}
// 向外暴露Promise函数
window.Promise = Promise
})(window)
Promise构造器
function Promise(executor) {
//将当前promise对象存起来 ,
const that = this
that.status = PENDING //给promise指定status属性,初始值为pending
that.data = undefined //给promise对象指定一个用于储存结果数据的属性
that.callbacks = [] //每个元素的结构 { onResolved() {}, onRejected() {} }
function resolve(value) {
//如果状态表示peddling,直接结束
if (that.status !== PENDING) {
return
}
//将状态改为resolved
that.status = RESOLVEED
//保存value数据
that.data = value
//如果有待执行的callback函数,立即异步执行回调onResolved() {}
if (that.callbacks.length > 0) {//放入队列执行所有成功的回调
setTimeout(() => {
that.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
});
});
}
}
function reject(reason) {
//如果状态表示peddling,直接结束
if (that.status !== PENDING) {
return
}
//将状态改为resolved
that.status = REJECTED
//保存value数据
that.data = reason
//如果有待执行的callback函数,立即异步执行回调onResolved() {}
if (that.callbacks.length > 0) {//放入队列执行所有成功的回调
setTimeout(() => {
that.callbacks.forEach(callbackObj => {
callbackObj.onRejected(reason)
});
});
}
}
// 立即同步执行excutor
try {
executor(resolve, reject)
} catch (error) {//如果执行器抛出异常 promise对象变为reje状态
reject(error)
}
}
Promise.prototype.then
/*
promise原型对象then()
指定成功和失败的会调函数
返回一个新的promise
返回promise的结果由onResolved/onRejected执行的结果决定
*/
Promise.prototype.then = function (onResolved, onRejected) {
const that = this
//指定回调函数的默认值
onResolved = typeof onResolved === 'function' ? onResolved : value => { return value }
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
//返回一个新的promise
return new Promise((resolve, reject) => {
/*
执行指定的回调函数
根据执行的结果改变return 的promise的状态/数据
*/
function handle(callback) {
//当前promise状态是resolved
/*
情况一 抛出异常,promise的结果为失败 reason为异常
情况二 如果返回的是promise 返回promise的结果就是这个promise的结果
情况三 如果返回的不是promise 返回promise为成功 value就是返回值
*/
try {
const result = callback(that.data)//接收结果
if (result instanceof Promise) {//如果返回的是promise 返回promise的结果就是这个promise的结果
/* result.then(
value =>{return resolve(value)},
reason =>{return reject(reason)}
) */
result.then(resolve, reject)
} else {//如果返回的不是promise 返回promise为成功 value就是返回值
resolve(result)
}
} catch (error) {
reject(error)//抛出异常,promise的结果为失败 reason为异常
}
}
if (that.status === RESOLVEED) {
//立即异步执行成功回调
setTimeout(() => {
handle(onResolved)
})
} else if (that.status === REJECTED) {//当前promise状态是rejected
setTimeout(() => {
handle(onRejected)
});
} else { // 当前promise状态是Pending
//向成功和失败的回调函数保存在callbacks容器中缓存起来
that.callbacks.push({
onResolved(value) {
handle(onResolved)
},
onRejected(reason) {
handle(onRejected)
}
})
}
})
}
Promise.prototype.catch
/*
promise原型对象catch()
promise原型对象then()
指定失败的会调函数
返回一个新的promise
*/
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
Promise.resolve
/**
* Promise函数对象resolve方法
* @param {*} value 成功的值
* @returns 一个成功/失败的promise
*/
Promise.resolve = function (value) {
// 返回一个成功/失败的promise
return new Promise((resolve, reject) => {
if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
value.then(resolve,reject)
} else { // value不是promise => promise状态变为成功,数据是value
resolve(value)
}
})
}
Promise.reject
/**
* Promise函数对象reject方法
* @param {*} resaon 失败的原因
* @returns 一个失败的promise
*/
Promise.reject = function (reason) {
// 返回一个失败的promise
return new Promise((resolve, reject) => {
reject(reason)
})
}
Promise.all
/* promise 函数对象all()
返回一个promise:只有当使用promise都成功才成功 否则只要有一个失败就失败
*/
Promise.all = function (promises) {
//保存所有成功value的数组
const values = new Array(promises.length)
//用来保存成功Promise的数量
let resolveCount = 0
//返回一个新的promise
return new Promise((resolve, reject) => {
//遍历获取每个promise的结果
promises.forEach((p, index) => {
Promise.resolve(p).then(// 防止数组中有不是promise的元素
value => {
resolveCount++ //成功数量加1
// p成功,将成功的value保存在values
values[index] = value
//如果全部成功,将return的promise改为成功
if (resolveCount == promises.length) {
resolve(values)
}
},
reason => {//只要一一个失败就整个失败,return Promise
reject(reason)
}
)
})
})
}
Promise.race
/* promise 函数对象race()
返回一个promise:其结果由第一个完成的promise决定
*/
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(resolve, reject)
})
})
}
class版
/*
自定义Promise函数模块: IIFE
*/
(function (window) {
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
class Promise {
/*
Promise构造函数
excutor: 执行器函数(同步执行)
*/
constructor(excutor) {
// 将当前promise对象保存起来
const self = this
self.status = PENDING // 给promise对象指定status属性, 初始值为pending
self.data = undefined // 给promise对象指定一个用于存储结果数据的属性
self.callbacks = [] // 每个元素的结构: { onResolved() {}, onRejected() {}}
function resolve (value) {
// 如果当前状态不是pending, 直接结束
if (self.status!==PENDING) {
return
}
// 将状态改为resolved
self.status = RESOLVED
// 保存value数据
self.data = value
// 如果有待执行callback函数, 立即异步执行回调函数onResolved
if (self.callbacks.length>0) {
setTimeout(() => { // 放入队列中执行所有成功的回调
self.callbacks.forEach(calbacksObj => {
calbacksObj.onResolved(value)
})
});
}
}
function reject (reason) {
// 如果当前状态不是pending, 直接结束
if (self.status!==PENDING) {
return
}
// 将状态改为rejected
self.status = REJECTED
// 保存value数据
self.data = reason
// 如果有待执行callback函数, 立即异步执行回调函数onRejected
if (self.callbacks.length>0) {
setTimeout(() => { // 放入队列中执行所有成功的回调
self.callbacks.forEach(calbacksObj => {
calbacksObj.onRejected(reason)
})
});
}
}
// 立即同步执行excutor
try {
excutor(resolve, reject)
} catch (error) { // 如果执行器抛出异常, promise对象变为rejected状态
reject(error)
}
}
/*
Promise原型对象的then()
指定成功和失败的回调函数
返回一个新的promise对象
返回promise的结果由onResolved/onRejected执行结果决定
*/
then (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) {
/*
返回promise的结果由onResolved/onRejected执行结果决定
1. 抛出异常, 返回promise的结果为失败, reason为异常
2. 返回的是promise, 返回promise的结果就是这个结果
3. 返回的不是promise, 返回promise为成功, value就是返回值
*/
try {
const result = callback(self.data)
if (result instanceof Promise) { // 2. 返回的是promise, 返回promise的结果就是这个结果
/*
result.then(
value => resolve(vlaue),
reason => reject(reason)
) */
result.then(resolve, reject)
} else { // 3. 返回的不是promise, 返回promise为成功, value就是返回值
resolve(result)
}
} catch (error) { // 1. 抛出异常, 返回promise的结果为失败, reason为异常
reject(error)
}
}
// 当前promise的状态是resolved
if (self.status===RESOLVED) {
// 立即异步执行成功的回调函数
setTimeout(() => {
handle(onResolved)
})
} else if (self.status===REJECTED) { // 当前promise的状态是rejected
// 立即异步执行失败的回调函数
setTimeout(() => {
handle(onRejected)
})
} else { // 当前promise的状态是pending
// 将成功和失败的回调函数保存callbacks容器中缓存起来
self.callbacks.push({
onResolved (value) {
handle(onResolved)
},
onRejected (reason) {
handle(onRejected)
}
})
}
})
}
/*
Promise原型对象的catch()
指定失败的回调函数
返回一个新的promise对象
*/
catch (onRejected) {
return this.then(undefined, onRejected)
}
/*
Promise函数对象的resolve方法
返回一个指定结果的成功的promise
*/
static resolve = function (value) {
// 返回一个成功/失败的promise
return new Promise((resolve, reject) => {
// value是promise
if (value instanceof Promise) { // 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // value不是promise => promise变为成功, 数据是value
resolve(value)
}
})
}
/*
Promise函数对象的reject方法
返回一个指定reason的失败的promise
*/
static reject = function (reason) {
// 返回一个失败的promise
return new Promise((resolve, reject) => {
reject(reason)
})
}
/*
Promise函数对象的all方法
返回一个promise, 只有当所有proimse都成功时才成功, 否则只要有一个失败的就失败
*/
static all = function (promises) {
// 用来保存所有成功value的数组
const values = new Array(promises.length)
// 用来保存成功promise的数量
let resolvedCount = 0
// 返回一个新的promise
return new Promise((resolve, reject) => {
// 遍历promises获取每个promise的结果
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
resolvedCount++ // 成功的数量加1
// p成功, 将成功的vlaue保存vlaues
// values.push(value)
values[index] = value
// 如果全部成功了, 将return的promise改变成功
if (resolvedCount===promises.length) {
resolve(values)
}
},
reason => { // 只要一个失败了, return的promise就失败
reject(reason)
}
)
})
})
}
/*
Promise函数对象的race方法
返回一个promise, 其结果由第一个完成的promise决定
*/
static race = function (promises) {
// 返回一个promise
return new Promise((resolve, reject) => {
// 遍历promises获取每个promise的结果
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {// 一旦有成功了, 将return变为成功
resolve(value)
},
reason => { // 一旦有失败了, 将return变为失败
reject(reason)
}
)
})
})
}
/*
返回一个promise对象, 它在指定的时间后才确定结果
*/
static resolveDelay = function (value, time) {
// 返回一个成功/失败的promise
return new Promise((resolve, reject) => {
setTimeout(() => {
// value是promise
if (value instanceof Promise) { // 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // value不是promise => promise变为成功, 数据是value
resolve(value)
}
}, time)
})
}
/*
返回一个promise对象, 它在指定的时间后才失败
*/
static rejectDelay = function (reason, time) {
// 返回一个失败的promise
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}
}
// 向外暴露Promise函数
window.Promise = Promise
})(window)
边栏推荐
猜你喜欢
PHP中 比较 0、false、null,‘‘ “
35-Jenkins-共享库应用
[Yellow ah code] Introduction to MySQL - 3. I use select, the boss directly drives me to take the train home, and I still buy a station ticket
XSS详解
使用MySQL如何查询一年中每月的记录数
MySql 5.7.38下载安装教程 ,并实现在Navicat操作MySql
力扣 593. 有效的正方形
初识NK-RTU980开发板
C语言三子棋(井字棋)小游戏
云服务器部署 Web 项目
随机推荐
How on one machine (Windows) to install two MYSQL database
Practical Bioinformatics 2: Multi-omics data integration and mining
如何在 Linux 上安装 MySQL
【MySQL功法】第4话 · 和kiko一起探索MySQL中的运算符
普通函数的参数校验
SSM框架讲解(史上最详细的文章)
【pytorch记录】pytorch的分布式 torch.distributed.launch 命令在做什么呢
Spark 在 Yarn 上运行 Spark 应用程序
报销流程|By天放师兄
使用MySQL如何查询一年中每月的记录数
@Transactional注解的失效场景
【MySQL功法】第2话 · 数据库与数据表的基本操作
MySQL 5.7详细下载安装配置教程
科目三:左转弯
jupyter notebook初使用
sqlmap使用教程大全命令大全(图文)
How to upgrade nodejs version
【MySQL功法】第5话 · SQL单表查询
Linux redis6.2.6 configuration file
关于“算力”,这篇文章值得一看