1.规范:https://promisesaplus.com/
2.测试promise: https://www.npmjs.com/package/promises-aplus-tests
3.实现一个promise.all , promise.race, promise.finally
// all 接收一个promise数组,返回一个promise,并且是一个失败即失败,全成功才成功
Promise.all = arr => {
return new Promise((resolve, reject) => {
let result = [], count = 0;
for (let i = 0; i < arr.length; i++) {
arr[i].then(val => {
result[i] = val
if(++count === arr.length) {
resolve(result)
}
}, reject)
}
})
}
// race 接收一个promise数组,返回一个promise,并且是一个失败即失败,一个成功即成功
Promise.race = arr => {
return new Promise((resolve, reject) => {
let result = [];
for (let i = 0; i < arr.length; i++) {
arr[i].then(resolve, reject)
}
})
}
// 不管成功还是失败都会执行
Promise.prototype.finally = fn => {
return this.then(val => {
fn()
}, err => {
fn()
})
}
- 实现过程
const PENDING = 'pending'
const FUILFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(executor) {
let self = this
self.status = PENDING
self.onFuilfilledCb = []
self.onRejectedCb = []
self.value = undefined
self.reason = undefined
function resolve(val) { // 2.1.2
// setTimeout(() => {
if (self.status === PENDING) {
self.status = FUILFILLED
self.value = val
self.onFuilfilledCb.forEach(cb => cb(val))
}
// }, 0)
}
function reject (reason) { // 2.1.3
// setTimeout(function(){
if (self.status === PENDING) {
self.status = REJECTED
self.reason = reason
self.onRejectedCb.forEach(cb => cb(reason))
}
// },0)
}
try{
executor(resolve, reject)
} catch (err) {
reject(err)
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:function(value){return value};
onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason};
let self = this
let promise2;
if(this.status === FUILFILLED) {
promise2 = new Promise((resolve, reject) => {
setTimeout(() =>{
try {
let x = onFulfilled(self.value)
resolvePromise(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
})
}
if(this.status === REJECTED) {
promise2 = new Promise((resolve, reject) => {
setTimeout(() =>{
try {
let x = onRejected(self.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
})
}
if(self.status === PENDING) {
promise2 = new Promise((resolve, reject) => {
self.onFuilfilledCb.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(self.value)
resolvePromise(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
})
})
self.onRejectedCb.push(() => {
setTimeout(() => {
try {
let x = onRejected(self.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
})
})
})
}
return promise2
}
Promise.prototype.catch = function(onRejected) {
this.then(null, onRejected)
}
Promise.deferred = Promise.defer = function(){
let defer = {};
defer.promise = new Promise(function(resolve,reject){
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
function resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x) {
return reject(new TypeError('循环引用'))
}
let called = false
if (x !== null && (typeof x === 'object' || typeof x === 'function')) { // 2.3.3
try {
let then = x.then
if (typeof then === 'function') {
then.call(x, y => {
if (called) return
called = true
resolvePromise(promise2, y, resolve, reject)
}, err => {
if (called) return
called = true
reject(err)
})
} else {
resolve(x)
}
} catch(err) {
if (called) return
called = true
reject(err)
}
} else {
resolve(x)
}
}
Promise.resolve = function(value){
return new Promise(function(resolve){
resolve(value);
});
}
//返回一个立刻失败的promise
Promise.reject = function(reason){
return new Promise(function(resolve,reject){
reject(reason);
});
}
// mjs
module.exports = Promise;
网友评论