最简易版本 promise
- 源码
function MyPromise(callback) {
// 定义 promise 内部的 status 和 value 值
let _this = this
this.status = 'pending'
this.value = null
this.resolveFunArr = []
this.rejectFunArr = []
function resolve(value) {
if (_this.status === 'pending') {
_this.status = 'resolved'
_this.value = value
_this.resolveFunArr.forEach(item => {
item(_this.value)
});
}
}
function reject(value) {
if (_this.status === 'pending') {
_this.status = 'rejected'
_this.value = value
_this.rejectFunArr.forEach(item => {
item(_this.value)
})
}
}
// try {
callback(resolve, reject)
// } catch (err) {
// reject(err)
// }
}
MyPromise.prototype.then = function (resolve, reject) {
let _this = this
if (_this.status == 'resolved') {
resolve(_this.value)
}
if (_this.status == 'rejected') {
reject(_this.value)
}
if (_this.status == 'pending') {
_this.resolveFunArr.push(resolve)
_this.rejectFunArr.push(reject)
}
}
var testPromise = new MyPromise((resolve, reject) => {
setTimeout(() => {
var number = Math.random();
if (number <= 0.5) {
resolve('less than 0.5');
} else {
reject('greater than 0.5');
}
}, 1000)
})
testPromise.then(data => {
console.log(data)
}, dataReject => {
console.log(dataReject)
})
- 思路整理
-
分析正常使用时候如何实例化调用,认知梳理需求。
由调用可知,一个 promse 可分为两部分: 一个是 注册阶段,一个是 调用阶段。注册阶段:我们使用 promise 的时候会先实例化一个 promise ,在这里我们会传过来一个 function(箭头函数),这个方法里面又包含了两个参数(resolve, reject)。而看代码可知这两个参数也都是 function (调用了 function),如下:
(resolve, reject) => { setTimeout(() => { var number = Math.random(); if (number <= 0.5) { resolve('less than 0.5'); } else { reject('greater than 0.5'); } }, 1000) }
调用阶段:看代码可知 .then 方法是在 promise 原型上注册的方法,因为每个 promise 方法都有这个方法。代码如下:
testPromise.then(data => { console.log(data) }, dataReject => { console.log(dataReject) })
-
实现简易版的 promise 源码
- 注册阶段:定义一个 promise 构造函数,在构造函数内部定义状态,及将方法放在一个数组里面,使其在调用阶段可以调
function MyPromise(callback) { // 定义 promise 内部的 status 和 value 值 let _this = this this.status = 'pending' // 初始化 promise 的状态 this.value = null // 将 resolve, reject 的值存储起来,因为两个只能触发一个,所以只需一个变量 this.resolveFunArr = [] // 将定义阶段的 resolve 方法 放在数组里面,方便调用阶段调用 this.rejectFunArr = [] // 将定义阶段的 reject方法 放在数组里面,方便调用阶段调用 function resolve(value) { if (_this.status === 'pending') { _this.status = 'resolved' // 改变状态,触发阶段依据此值执行 resolveFunArr 数组里面的方法 _this.value = value // 将 resolve 的值储存起来 _this.resolveFunArr.forEach(item => { item(_this.value) }); } } function reject(value) { if (_this.status === 'pending') { _this.status = 'rejected' // 改变状态,触发阶段依据此值执行 rejectFunArr 数组里面的方法 _this.value = value // 将 reject 的值储存起来 _this.rejectFunArr.forEach(item => { item(_this.value) }) } } // try { callback(resolve, reject) // } catch (err) { // reject(err) // 兼容写法,报错时候将错误抛出来 // } }
- 调用阶段
在原型上注册 .then 方法 并根据 status 的值执行方法MyPromise.prototype.then = function (resolve, reject) { let _this = this if (_this.status == 'resolved') { resolve(_this.value) } if (_this.status == 'rejected') { reject(_this.value) } if (_this.status == 'pending') { _this.resolveFunArr.push(resolve) _this.rejectFunArr.push(reject) } }
- 注册阶段:定义一个 promise 构造函数,在构造函数内部定义状态,及将方法放在一个数组里面,使其在调用阶段可以调
-