小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
Promise项目构建
- self-promise 文件夹
-
lib 存放js文件
- promise.js 函数
-
index.html 测试promise
-
- promise.js 函数 基础构建 (ES5语法)
// 自定义promise函数 模块
(function (window) {
/*
Promise 构造函数
excutor 执行器函数(同步)
*/
function Promise(excutor) {
}
/*
Promise原型上的then方法
指定成功和失败的回调函数
返回一个新的promise对象
*/
Promise.prototype.then = function (onResolved, onRjected) {
}
/*
Promise原型上的catch方法
指定失败的回调函数
返回一个新的promise对象
*/
Promise.prototype.catch = function (onRjected) {
}
/*
Promise函数对象的resolve方法
返回一个指定value的成功promise
*/
Promise.resolve = function (value) {
}
/*
Promise函数对象的reject方法
返回一个指定reason的失败promise
*/
Promise.reject = function (reson) {
}
/*
Promise函数对象的all方法
返回一个promise,只有当所有promise都成功时,否则失败
*/
Promise.all = function (promises) {
}
/*
Promise函数对象的race方法
返回一个promise,结果由第一个完成的promise决定
*/
Promise.race = function (promises) {
}
// 向外暴露Promise函数
window.Promise = Promise
})(window)
Promise 函数
// 定义常量
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function Promise(excutor) {
// 将当前promise保存起来
const _that = this
_that.status = PENDING // 给promise对象指定status属性, 初始值为pending
_that.data = undefined // 给promise对象指定一个用于存储结果数据的属性
_that.callbacks = [] // 每个元素的结构 {onResolved() {}, onRejected() {}}
function resolve(value) {
// 如果当前状态不是pending 直接结束
if (_that.status !== PENDING) {
return
}
// 将状态改为resolved
_that.status = RESOLVED
//保存value数据
_that.data = value
// 如果有待执行的callbacks函数, 立即异步执行回调函数
if (_that.callbacks.length > 0) {
setTimeout(() => { // 放入队列中执行所有成功的回调
_that.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
});
})
}
}
function reject(reason) {
// 如果当前状态不是pending 直接结束
if (_that.status !== PENDING) {
return
}
// 将状态改为reject
_that.status = REJECTED
//保存value数据
_that.data = reason
// 如果有待执行的callbacks函数, 立即异步执行回调函数
if (_that.callbacks.length > 0) {
setTimeout(() => { // 放入队列中执行所有失败的回调
_that.callbacks.forEach(callbacksObj => {
callbacksObj.onRjected(reason)
});
})
}
}
// 立即同步执行 执行器 内部调用 resolve reject
// 如果发生异常 直接触发失败
try {
excutor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.then方法
Promise.prototype.then = function (onResolved, onRjected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value
// 指定默认的失败回调 实现错误、异常穿透的关键
onRjected = typeof onRjected === 'function' ? onRjected : reason => { throw reason }
const _that = this
// 返回一个新的promise
return new Promise((resolve, reject) => {
/*
调用指定函数处理 根据执行的结果改变return的promise状态
*/
function handle(callback) {
/*
1. 如果执行抛出异常,return的promise就会失败,reason就是error
2. 如果回调函数执行返回非promise,return的promise就会成功,value就是返回的值
3. 如果回调函数执行返回是promise,return的promise就是这个promise的结果
*/
try {
const result = callback(_that.data)
// 3. 如果回调函数执行返回是promise,return的promise就是这个promise的结果
if (result instanceof Promise) {
// 基础语法
// result.then(
// value =>resolve(value), // result 成功时,让return的promise也成功
// reason =>reject(reason) // result 失败时,让return的promise也失败
// )
// 简洁语法
result.then(resolve, reject)
} else {
// 2. 如果回调函数执行返回非promise,return的promise就会成功,value就是返回的值
resolve(result)
}
// 1. 如果执行抛出异常,return的promise就会失败,reason就是error
} catch (error) {
reject(error)
}
}
// 当前状态是pending 将回调函数保存起来
if (_that.status == PENDING) {
_that.callbacks.push({
onResolved(value) {
handle(onResolved)
},
onRjected(reason) {
handle(onRjected)
}
})
} else if (_that.status = RESOLVED) { // 如果当前是resolve状态,异步执行onResolved并改变promise状态
setTimeout(() => {
handle(onResolved)
})
} else { //'rejected'
setTimeout(() => { // 如果当前是rejected状态,异步执行onRejected并改变promise状态
handle(onRjected)
})
}
})
}
Promise.catch
//直接返回错误即可
Promise.prototype.catch = function (onRjected) {
return this.then(undefined, onRjected)
}
总结
- 今天手写了Promise函数及then和catch方法 剩余的明天再更
- class版本明天改写..... 敬请期待