83 lines
2.8 KiB
JavaScript
83 lines
2.8 KiB
JavaScript
|
||
// 手写一个Promise
|
||
function MyPromise(fun){ // 构造函数接收一个函数
|
||
this.status = MyPromise.PENDING // 设置默认状态为待定
|
||
try {
|
||
fun.call(this, MyPromise.resolve.bind(this), MyPromise.reject.bind(this))
|
||
} catch(err){
|
||
// 如果MyPromise.prototype.then里面有err=>{}处理函数就传递给它
|
||
this.status = MyPromise.REJECT
|
||
this.result = err
|
||
}
|
||
|
||
}
|
||
|
||
// Promise 状态常量
|
||
MyPromise.PENDING = 0
|
||
MyPromise.FULFILLED = 1
|
||
MyPromise.REJECT = 2
|
||
|
||
|
||
MyPromise.resolve = function(res) {
|
||
if(this === MyPromise) return new MyPromise(resolve=>resolve(res)) // 如果是静态调用就返回一个确认的Promise
|
||
if(this.status === MyPromise.REJECT) return // Promise 的状态一旦确定就不能修改
|
||
this.status = MyPromise.FULFILLED
|
||
this.result = res
|
||
}
|
||
|
||
MyPromise.reject = function(err) {
|
||
if(this === MyPromise) return new MyPromise((resolve,reject)=>reject(err)) // 如果是静态调用就返回一个拒绝的Promise
|
||
if(this.status === MyPromise.FULFILLED) return // Promise 的状态一旦确定就不能修改
|
||
this.status = MyPromise.REJECT
|
||
this.result = err
|
||
}
|
||
|
||
MyPromise.prototype = {
|
||
then: function(res, err){
|
||
// Promise的.then要加入到任务队列,不能同步执行用setTimeout模拟
|
||
var context = this // 保存的上下文
|
||
setTimeout(function(){
|
||
// 在.then中无论是onFulfilled的返回值还是onReject的返回值,都会交给下一个.then的onFulfilled处理,只有出现异常的时候才后交给下一个.then的onReject处理
|
||
try{
|
||
if(context.status === MyPromise.FULFILLED && res) context.result = res(context.result)
|
||
if(context.status === MyPromise.REJECT && err) {
|
||
context.result =err(context.result)
|
||
context.status = MyPromise.FULFILLED
|
||
}
|
||
}catch(err){
|
||
context.result = err
|
||
context.status = MyPromise.REJECT
|
||
}
|
||
}, 0);
|
||
return this
|
||
}
|
||
}
|
||
|
||
// 编写Promise.all([...Promies])静态方法
|
||
|
||
/**
|
||
* @description 接受一个Promise的迭代对象,当全部的Promise兑现时,返回一个由兑现值组成的迭代对象
|
||
* 当为空的迭代对象时也会对象一个空的迭代对象 Promise.all([]).then(res=>{console.log(res)}) res = []
|
||
*/
|
||
MyPromise.all = function (ps) {
|
||
if(typeof ps[Symbol.iterator] !== 'function') throw new Error("传递一个内容为Promise实例的可迭代对象")
|
||
var n = ps.length
|
||
var rs = []
|
||
for(var i = 0; i < n; i++) {
|
||
(function(i){
|
||
ps[i].then(res=>{
|
||
rs[i] = res
|
||
}, err=>{
|
||
// all只要出现拒绝,就立马返回第一个拒绝的内容
|
||
this.status = MyPromise.REJECT;
|
||
this.result = err
|
||
})
|
||
}).call(this, i)
|
||
}
|
||
if (this.status === MyPromise.REJECT) return this
|
||
|
||
this.status = MyPromise.FULFILLED
|
||
this.result = rs
|
||
return this
|
||
}
|