先写一个最简单的同步的Promise,
首先根据Promise的A+规范
// Promise三个状态,pending,fulfilled,rejected .两个值value,reason.
// Promise接收回调函数,回调函数的参数为resolve跟reject
//
// then方法
// promise.then(onFulfilled(接受Promise的value值), onRejected(接收Promise的reason值))
//使用try catch处理报错
<script>
var PENDING = 'pending'
var FULFILLED = 'fulfilled'
var REJECTED = 'rejected'
function myPromise(callBack) {
var that = this
that.status = PENDING
function resolve(value) {
if (that.status === PENDING){
that.status = FULFILLED
that.value = value
}
}
function reject(reason) {
if (that.status === PENDING){
that.status = REJECTED
that.reason = reason
}
}
try{
callBack(resolve,reject)
}catch (e) {
reject(e)
}
}
myPromise.prototype.then = function (onFulfilled,onRejected) {
onFulfilled = typeof onFulfilled === 'function'? onFulfilled: function (x) {return x}
onRejected = typeof onRejected === 'function'? onRejected: function (e) {throw e}
var that = this
if (that.status ===FULFILLED){
setTimeout(()=>{
onFulfilled(that.value)
})
}
if (that.status ===REJECTED){
setTimeout(()=>{
onRejected(that.reason)
})
}
}
</script>
上面是一个简易功能的Promise,但是仍有缺陷,
问题
1.Promise异步不能实现
2.then不能被链式调用,then函数的返回值不是promise
解决方法
1.在 PENDING 状态时,需要等到状态落定才能调用。我们可以将 onFulfilled 和 onRejected 函数存到 Promise 的属性 onFulfilledFn 和 onRejectedFn 中,
将 onFulfilledFn 和 onRejectedFn 改成数组。.resolve() 和 reject() 函数改变状态时,需要异步调用数组中的函数,同样使用 setTimeout 来模拟异步。
所以需要写的东西有:
that.onFulfilledFn=[]
that.onRejectedFn=[]
function resolve(value) {
setTimeout(function () {
if (that.state === PENDING) {
that.state = FULFILLED
that.value = value
that.onFulfilledFn.forEach(item=>item(that.value))
}
})
}
if (that.state === PENDING) {
return new myPromise(function (resolve,reject) {
that.onFulfilledFn.push(function() {
try {
onFulfilled(that.value);
} catch (reason) {
reject(reason);
}
})
that.onRejectedFn.push(function() {
try {
onRejected(that.reason);
} catch (reason) {
reject(reason);
}
});
})
}
2.链式调用,then返回一个新的promise,直接在方法里return new myPromise
<script>
// A+规范
//
// Promise三个状态,pending,fulfilled,rejected .两个值value,reason.
// Promise接收回调函数,回调函数的参数为resolve跟reject
//
// then方法
// promise.then(onFulfilled(接受Promise的value值), onRejected(接收Promise的reason值))
//使用try catch处理报错
// 1.then 方法接受两个函数作为参数,且参数可选。
// 2.如果可选参数不为函数时会被忽略。
// 3.两个函数都是异步执行,会放入事件队列等待下一轮 tick。
// 4.当调用 onFulfilled 函数时,会将当前 Promise 的 value 值作为参数传入。
// 5.当调用 onRejected 函数时,会将当前 Promise 的 reason 失败原因作为参数传入。
// 6.then 函数的返回值为 Promise。
// 7.then 可以被同一个 Promise 多次调用(then的链式)。
// * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
// * 2. executor 接受两个参数,分别是 resolve 和 reject
// * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
// * 4. promise 的状态一旦确认,就不会再改变
// * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,
// * 和 promise 失败的回调 onRejected
// * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。
// * 如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
// * 如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)
// * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
// * 8. promise 可以then多次,promise 的then 方法返回一个 promise
// * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)
// * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)
// * 11.如果 then 返回的是一个promise,那么会等这个promise执行完,promise如果成功,
// * 就走下一个then的成功,如果失败,就走下一个then的失败
// *
var PENDING = 'pending';
var FULFILLED = 'fulfilled';
var REJECTED = 'rejected';
//简易Promise,传入一个回调函数,回调函数的参数是resolve()和reject()
function myPromise(callBack) {
var that = this;
that.state = PENDING
that.onFulfilledFn = [];
that.onRejectedFn = [];
function resolve(value) {
setTimeout(function () {
if (that.state === PENDING) {
that.state = FULFILLED
that.value = value;
that.onFulfilledFn.forEach(function (fn) {
fn(that.value)
})
}
})
}
function reject(reason) {
setTimeout(function () {
if (that.state === PENDING) {
that.state = REJECTED
that.reason = reason
that.onRejectedFn.forEach(function(fn){
fn(that.reason)
})
}
})
}
//Promise 内部的异常不能直接抛出,需要进行异常捕获。
try {
callBack(resolve, reject)
} catch (e) {
reject(e)
}
}
//原型定义方法和共享属性
myPromise.prototype.then = function (onFulfilled, onRejected) {
//then规则2,可选参数不为函数时应该被忽略
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : function (x) {
return x
}
onRejected = typeof onRejected === "function" ? onRejected : function (e) {
throw e
}
var that = this;
//以下if语句为对onFulfilled, onRejected等方法传参,then规则3异步,then规则4,5
//then规则6,then返回Promise
if (that.state === FULFILLED) {
return new myPromise((resolve, reject) => {
setTimeout(function () {
try {
onFulfilled(that.value)
} catch (e) {
reject(e)
}
})
})
}
if (that.state === REJECTED) {
return new myPromise((resolve, reject) => {
setTimeout(function () {
try {
onRejected(that.reason)
} catch (e) {
reject(e)
}
})
})
}
//在 PENDING 状态时,需要等到状态落定才能调用。我们可以将 onFulfilled 和 onRejected 函数存到 Promise 的属性 onFulfilledFn 和 onRejectedFn 中
//为了支持then的链式调用,下面的代码如
if (that.state === PENDING) {
return new myPromise(function(resolve, reject) {
that.onFulfilledFn.push(function() {
try {
onFulfilled(that.value);
} catch (reason) {
reject(reason);
}
})
that.onRejectedFn.push(function() {
try {
onRejected(that.reason);
} catch (reason) {
reject(reason);
}
});
});
}
}
let Fsskay = new myPromise((resolve, reject) => {
setTimeout(function () {
resolve(123)
},1000)
})
Fsskay.then((data) => {
console.log(data)
})
console.log(Fsskay)
</script>