start
- 花了两个小时手写了一个Promise,也算是说做就做,没有拖延。
- 不管写的好坏与否,对Promise掌握程度还是有很大提升,写完的感受就很爽。
(*^▽^*)
- 暂时就写完整版吧,相关思路注释写的很详细了。
Promise.js
// 1 创建一个 函数 叫 Promise
function Promise(executor) {
// 3 实例上有几个属性
this.PromiseState = 'pending'
this.PromiseResult = undefined
this.callBack = []
let that = this
// 4 匿名函数有两个参数 也是函数 当他们执行的时候,去修改状态和输出结果
function resolve(data) {
// 6 实例状态只能修改一次
if (that.PromiseState !== 'pending') return
that.PromiseState = 'fulfilled'
that.PromiseResult = data
// 25 ① then的返回值修改为异步的
setTimeout(() => {
that.callBack.forEach(element => {
element.resolved(that.PromiseResult)
});
})
}
function reject(data) {
if (that.PromiseState !== 'pending') return
that.PromiseState = 'rejected'
that.PromiseResult = data
// 25 ②
setTimeout(() => {
that.callBack.forEach(element => {
element.rejected(that.PromiseResult)
});
})
}
// 5 处理一下 匿名函数运行的异常,如果有错误,直接reject
try {
// 2 Promise接受一个参数可以执行
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// 7 实例的then方法
Promise.prototype.then = function (resolved, rejected) {
// 17 兼容 then 参数可以为 0个 1个 两个 的写法
if (typeof resolved !== 'function') { onResolved = value => value; }
if (typeof rejected !== 'function') { onRejected = reason => { throw reason; } }
let that = this
/** 11:
* 1. then方法返回的也是一个 Promise对象
* 2. 返回一个什么样的Promise对象呢?
* + 如果本身就返回的一个Promise对象,就不做改变直接返回
* + 如果是`非Promise对象`,就返回一个状态为成功,值为这个 `非Promise对象` 的一个Promise对象
* + 如果 返回值是一个异常,就返回一个状态为失败,值为异常信息 的一个Promise对象
*
* 3. 我这里在想在代码最后直接return一个promise对象不可以吗? 包裹起来比较好,取值以及异步逻辑都有优点??
* 4. 为了方便区分,不和then接收的参数混淆,我在返回的Promise对象的参数前面加了 `to`
*/
return new Promise(function (toResolve, toReject) {
// 16 都是try catch 所以抽取公共方法; 执行的不一样所以type作为参数
function callBack(type) {
try {
let result = type(that.PromiseResult)
if (result instanceof Promise) {
result.then(v => { toResolve(v); }, r => { toReject(r); })
} else {
toResolve(result)
}
} catch (error) {
toReject(error)
}
}
// 8 then中可以传递两个参数 根据实例的状态去做执行
if (that.PromiseState === 'fulfilled') {
// try {
// // 9 如果执行then方法时,状态都已经改变了
// let result = resolved(this.PromiseResult)
// if (result instanceof Promise) {
// result.then(v => { toResolve(v); }, r => { toReject(r); })
// } else {
// toResolve(result)
// }
// } catch (error) {
// toReject(error)
// }
// 25 ③
setTimeout(() => {
callBack(resolved)
})
}
if (that.PromiseState === 'rejected') {
// // 14 异常处理 范湖
// try {
// // 13 处理一下then方法的返回值(只需要toResolve, toReject这两个方法执行即可) 这里的 rejected(this.PromiseResult) === function (this.PromiseResult) {console.log(2, err)}
// let result = rejected(this.PromiseResult)
// // 13.① 返回原本的Promise对象 (如果本身就返回的一个Promise对象,我们递归调用then方法 然后获取这个promise的状态然后返回)
// if (result instanceof Promise) {
// result.then(v => { toResolve(v); }, r => { toReject(r); })
// } else {
// // 13 ②
// toResolve(result)
// }
// } catch (error) {
// toReject(error)
// }
// 25 ④
setTimeout(() => {
callBack(rejected)
})
}
// 10 如果状态是 pending(如果执行then方法时,状态未改变)就等后续 状态改变的时候再去执行对应的方法,这里存储到实例的属性 数组callBack 中
if (that.PromiseState === 'pending') {
that.callBack.push({
// 15 pending 的函数怎么处理
resolved: function () {
callBack(resolved)
},
rejected: function () {
callBack(rejected)
}
})
}
})
}
// 18 实例的catch方法
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
}
// 19 实例的finally方法 ---其实就是 在finally中的语句 会在then catch都执行一遍,所以返回一个then方法即可
Promise.prototype.finally = function (fn) {
return this.then(data => { // then返回的也是一个Promise对象
fn(); // 执行回调,但不传递数据
return data; // 保证返回的Promise对象的数据一致
}, reason => {
fn();
throw reason; // 保证返回的Promise对象的数据状态一致
})
}
// 20 构造函数自身的方法 resolve
Promise.resolve = function (value) {
/**
* 参数
* Ⅰ-如果为promise:将其状态与结果赋值给外层promise对象
* Ⅱ-如果为非promise: 状态设置为成功,直接返回
*/
return new Promise(function (toResolve, toReject) {
if (value instanceof Promise) {
value.then(v => { toResolve(v) }, r => { toReject(r) })
} else {
toResolve(value)
}
})
}
// 21 构造函数自身的方法 reject
Promise.reject = function (value) {
/**
* 参数
* Ⅰ-如果为promise:将其状态与结果赋值给外层promise对象
* Ⅱ-如果为非promise:状态设置为失败
*/
return new Promise(function (toResolve, toReject) {
if (value instanceof Promise) {
value.then(v => { toResolve(v) }, r => { toReject(r) })
} else {
toReject(value)
}
})
}
// 22 Promise.all
Promise.all = function (promises) {
/**
* Promise.all([1,2,3])
*
* (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
* (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
*/
return new Promise(function (toResolve, toReject) {
let count = 0;
let arr = [];
for (let i = 0; i < promises.length; i++) {
let value = promises[i]
// 如果传入的不是promsie对象 给它转换为promise对象
if (!(value instanceof Promise)) {
value = Promise.resolve(value)
}
value.then(v => {
count++;
arr[i] = v;
if (count === promises.length) {
// 所有的成功了 就直接返回
toResolve(arr);
}
}, r => {
// 只要失败就直接返回
toReject(r)
})
}
})
}
// 23 Promise.allSettled
Promise.allSettled = function (promises) {
return new Promise(function (toResolve, toReject) {
let count = 0;
let arr = [];
for (let i = 0; i < promises.length; i++) {
let value = promises[i]
// 如果传入的不是promsie对象 给它转换为promise对象
if (!(value instanceof Promise)) {
value = Promise.resolve(value)
}
value.then(v => {
count++;
arr[i] = {
status: 'fulfilled', value: v
}
if (count === promises.length) {
toResolve(arr);
}
}, r => {
count++;
arr[i] = {
status: 'rejected', reason: r
}
if (count === promises.length) {
toResolve(arr);
}
})
}
})
}
// 24 Promise.race
Promise.race = function (promises) {
// 谁先执行就返回谁的运行结果
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
let value = promises[i]
// 如果传入的不是promsie对象 给它转换为promise对象
if (!(value instanceof Promise)) {
value = Promise.resolve(value)
}
value.then(v => {
resolve(v);
}, r => {
reject(r);
})
}
});
}