一、简单版本(干货)
1、未处理什么类型错误
function myPromise(executor) {
this.state = 'pending';
this.result = '';
this.fullfiledArr = [];
this.rejectedArr = [];
var change;
//注意这里要设置this,否则在change函数里面容易出现this丢失的情况
var self = this
change = function (state, result) {
if (self.state !== 'pending') return
self.state = state;
self.result = result;
setTimeout(function () {
var callArr = self.state == 'resolved' ? self.fullfiledArr : self.rejectedArr,
i = 0,
len = callArr.length;
for (;i < len;i++) {
callArr[i](self.result)
}
})
}
try {
executor(function (result) {
change('resolved', result)
}, function (reason) {
change('rejected', reason)
})
} catch (e) {
change('rejected', e)
}
}
function handle(newPromise, x, resolve, reject) {
if (x === newPromise) throw new TypeError('Chaining cycle detected for promise #<Promise>');
if (x instanceof myPromise) {
x.then(function (result) {
resolve(result)
}, function (err) {
reject(err)
})
} else {
resolve(x)
}
}
myPromise.prototype = {
constructor: myPromise,
then: function (onfullfiled, onrejected) {
if (typeof onfulfilled !== "function") {
onfulfilled = function onfulfilled(result) {
return result;
};
}
if (typeof onrejected !== "function") {
onrejected = function onrejected(reason) {
throw reason;
};
}
var self = this,
x,
newPromise = new myPromise(function (resolve, reject) {
if (self.state == 'resolved') {
//这里模仿异步微任务
setTimeout(function () {
try {
x = onfullfiled(self.result)
handle(newPromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else if (self.state == 'rejected') {
setTimeout(function () {
try {
x = onrejected(self.result)
handle(newPromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
} else {
self.fullfiledArr.push(function (result) {
try {
x = onfullfiled(result)
handle(newPromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
self.rejectedArr.push(function (reason) {
try {
x = onrejected(reason)
handle(newPromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
})
return newPromise
},
catch: function (onrejected) {
return this.then(null, onrejected)
}
}
2、实现Promise的all、resolve、reject方法
myPromise.resolve = function (result) {
return new myPromise(function (resolve) {
resolve(result)
})
}
myPromise.reject = function (reason) {
return new myPromise(function (resolve, reject) {
reject(reason)
})
}
myPromise.all = function (promiseArr) {
return new myPromise(function (resolve, reject) {
var i = 0,
len = promiseArr.length,
item,
resultArr = [];
for (;i < len;i++) {
item = promiseArr[i]
if (!(promiseArr[i] instanceof myPromise)) {
promiseArr[i] = myPromise.resolve(promiseArr[i])
}
(function (i) {
promiseArr[i].then(function (result) {
resultArr[i] = result
if (i == len) resolve(resultArr)
}, function (reason) {
reject(reason)
})
})(i)
}
})
}
3、实现promise的race方法
myPromise.race = function (promiseArr) {
return new myPromise(function (resolve, reject) {
var i = 0,
len = promiseArr.length,
item
for (;i < len;i++) {
item = promiseArr[i]
if (!(item instanceof myPromise)) {
item = myPromise.resolve(item)
}
item.then(function (result) {
resolve(result)
}, function (result) {
reject(result)
})
}
})
}