先把用法写出来
let p = new Pro((resolve, reject) => {
// throw new Error('something wrong')
setTimeout(() => {
resolve(11)
}, 1000)
// reject(12)
})
p.then(res => { return 99 }, err => {console.log('哦呀呀: ',err); return 888; })
.then(res => console.log('别有用心', res), err => console.log('哦呀呀: ',err))
然后来实现这个简单的
延时、非延时、简单链式
class Pro {
constructor (fn) {
this.fn = fn
this.status = 'pedding'
this.value = null
this.errmsg = null
this.resolveArr = []
this.rejectArr = []
this.user_resolve = res => {
this.resolveArr.length ? this.resolveArr.forEach(item => item[1](item[0](res))) : this.value = res
}
this.user_reject = errmsg => {
this.rejectArr.length ? this.rejectArr.forEach(item => item[1](item[0](errmsg))) : this.errmsg = errmsg
}
this.resolve = res => { if (this.status != 'pedding') return; this.status = 'success'; this.user_resolve(res) }
this.reject = err => { if (this.status != 'pedding') return; this.status = 'error'; this.user_reject(err) }
try {
this.fn(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
then (resolveFn, rejectFn) {
if (this.status == 'success') {
let res = resolveFn(this.value);
return new Pro(resolve => resolve(res))
}
else if (this.status == 'error') {
let res = rejectFn(this.errmsg);
return new Pro((resolve, reject) => reject(res))
}
else {
console.log('延时了')
return new Pro((resolve, reject) => {
this.resolveArr.push([resolveFn, resolve])
this.rejectArr.push([rejectFn, reject])
})
}
}
}
复杂链式,then返回promise
p.then(res => { return 99 }, err => {console.log('哦呀呀: ',err); return 888; })
p.then(res => {
return new Pro((resolve, reject) => reject('一个promise的返回'))
}, err => {
return new Pro((resolve, reject) => resolve('一个promise的错误'))
})
实现(完整代码在文章末尾)
...
this.user_resolve = res => {
this.resolveArr.length
? this.resolveArr.forEach(item => this.__handlerResolve(item[0](res), item[1], item[2]))
: this.value = res
}
this.user_reject = errmsg => {
this.rejectArr.length
? this.rejectArr.forEach(item => this.__handlerResolve(item[0](errmsg), item[1], item[2]))
: this.errmsg = errmsg
}
...
then (resolveFn, rejectFn) {
if (this.status == 'success') {
let res = resolveFn(this.value);
return new Pro(resolve => resolve(res))
return new Pro((resolve, reject) => this.__handlerResolve(res, resolve, reject))
}
else if (this.status == 'error') {
let res = rejectFn(this.errmsg);
return new Pro((resolve, reject) => reject(res))
let err = rejectFn(this.errmsg);
return new Pro((resolve, reject) => this.__handlerReject(err, resolve, reject))
}
else {
console.log('延时了')
return new Pro((resolve, reject) => {
this.resolveArr.push([resolveFn, resolve])
this.rejectArr.push([rejectFn, reject])
this.resolveArr.push([resolveFn, resolve, reject])
this.rejectArr.push([rejectFn, resolve, reject])
})
}
}
__handlerResolve (res, resolve_fn, reject_fn) {
if (res instanceof Pro) res.then(res2 => resolve_fn(res2), err => reject_fn(err))
else resolve_fn(res)
}
__handlerReject (err, resolve_fn, reject_fn) {
if (err instanceof Pro) err.then(res => resolve_fn(res), err2 => reject_fn(err2))
else reject_fn(err)
}
...
catch:then的一个别名
new Pro((resolve, reject) => { // mise
throw new Error("别名啊")
}).catch(err => console.log(err))
...
catch (fn) { return this.then(null, fn) }
...
Promise.resolve 和 Promise.reject
Promise.resolve('right man').then(res => console.log(res))
Promise.reject('loser').catch(res => console.log(res))
Pro.resolve = val => new Pro((resolve, reject) => resolve(val))
Pro.reject = err => new Pro((resolve, reject) => reject(err))
finally(es9)
// finally没入参
Promise.resolve('right man').finally(() => console.log('没参数')).then(res => console.log(res)) //-- right man
Promise.reject('loser').finally(() => console.log('错了也没参数')).catch(res => console.log(res)) //-- loser
// 无论如何都会执行
Promise.resolve('right man').then(res => console.log(res)).finally(() => console.log('没参数'))
Promise.reject('loser').catch(res => console.log(res)).finally(() => console.log('错了也没参数'))
// (非promise)不影响后续then(走向和参数)
Promise.resolve('right man').finally(() => '没参数').then(res => console.log(res)) //-- right man
Promise.reject('loser').finally(() => '错了也没参数').catch(res => console.log(res)) //-- loser
// promise返回值,执行完成后才会走后续then,可做sleep使用
// promise执行结果reject完全影响后续then,不影响后续then
Promise.resolve('right man').finally(() => {
return new Promise((reslove, reject) => {
setTimeout(() => {
reject('没参数') //-- (2s后打印) err 没参数
// reslove('没参数') //-- (2s后打印) right man
}, 2000)
})
}).then(res => console.log(res), err => console.log('err',err))
Promise.reject('loser').finally(() => {
return new Promise((reslove, reject) => {
setTimeout(() => {
reject('没参数') //-- (2s后打印) err 没参数
// reslove('没参数') //-- (2s后打印) err loser
}, 2000)
})
}).then(res => console.log(res), err => console.log('err',err))
...
// 一种特殊的then,fn没入参,(非promise)不影响后续then(走向和参数)
// promise返回值,执行完成后才会走后续then,可做sleep使用
// promise执行结果reject完全影响后续then,reslove不影响后续then
finally (fn) {
let handlerFn = (val, iserr) => {
let fn_return = fn()
if (fn_return instanceof Pro) {
return new Pro((resolve, reject) => {
fn_return.then(res => iserr ? reject(val) : resolve(val), err => reject(err))
})
} else return val
}
return this.then(res => handlerFn(res), err => handlerFn(err, true))
}
...
race
let p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1111"), 1000);
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p2222"), 500);
})
Promise.race([p1, p2]).then(res => console.log(res), err => console.log('err',err))
//--p2222
Pro.race = function (args) {
return new Pro((resolve, reject) => {
args.forEach(item => {
if (item && item.then && typeof item.then == 'function')
item.then(resolve, reject)
else
resolve(item)
})
})
}
all
let p1 = new Promise((resolve, reject) => {
setTimeout(() => reject("p1111"), 1000);
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p2222"), 500);
})
Promise.all([1,2, p1, p2]).then(res => console.log(res), err => console.log('err',err))
//--err p1111
//--[ 1, 2, 'p1111', 'p2222' ]
Pro.all = function (args) {
return new Pro((resolve, reject) => {
let arr = [],
beleft = args.length,
save = (val, index) => {
arr[index] = val
beleft--
if (beleft == 0) resolve(arr)
};
args.forEach((item, index) => {
if (item && item.then && typeof item.then == 'function')
item.then(res => save(res, index), err => reject(err))
else
save(item, index)
})
})
}
最后加了一些校验,如 promise 不能返回自己、处理变态空链(p.then().then()...)等
地址:https://gitee.com/claudia/Demo/blob/01789eeb644a93e340011bd8846f8dfb70322511/promise/index.js








网友评论