手写Promise——Day2
一、catch方法的实现
catch方法是用来捕获一个失败的Promise对象,然后在返回一个失败的Promise对象
代码:
//直接调用then方法来返回一个失败结果
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
}
复制代码
测试:
<script>
let p = new Promise((resolve, reject) => {
reject('err');
// resolve('ok');
})
p.catch((reason) => {
console.warn(reason)
})
console.log(p)
//当返回一个失败Promise时,如果不被catch,则会报错
</script>
复制代码
二、异常穿透与值传递
代码:
Promise.prototype.then = function(onResolved, onRejected) {
//只写了新需求的代码,之前重复的就没写了
return new Promise((resolve, reject) => {
//实现异常穿透时,通常会省略onRejected回调函数,所以我们需要在底层实现该逻辑
if (typeof onRejected !== 'function') {
onRejected = rea => {
throw rea // throw会返回一个失败的Promise
/*
如果返回的一个成功的Promise或者非Promise类型,则不会被cathch捕获到
如:return rea
console.log(rea)
*/
}
}
//实现值传递时,可能会省略onResolved回调函数,所以我们需要在底层实现该逻辑
if (typeof onResolved !== 'function') {
onResolved = val => {
return val;
}
}
}
}
复制代码
测试:
<script>
let p = new Promise((resolve, reject) => {
reject('err');
// resolve('ok');
})
//异常穿透,只要有一个出错,就被捕获到catch中去
p.then(value => {
console.log(111);
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason)
})
//值传递,对应需要成功回调
p.then()
.then(value => {
console.log(222);
}).then(value => {
console.log(333);
})
console.log(p)
</script>
复制代码
三、resolve方法的实现
该方法是Promise构造函数身上的一个方法,且返回对象和then方法是一样的
1.如果回调函数结果是一个非Promise对象,则返回一个成功的Promise
2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定
代码:
//所以该代码实现逻辑和then方法中类似
Promise.resolve = function(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(val => {
resolve(val);
}, rea => {
reject(rea);
})
} else {
resolve(value);
}
});
}
复制代码
测试:
<script>
let p1 = Promise.resolve('ok');
let p2 = Promise.resolve(new Promise((resolve, reject) => {
resolve('okkk');
}));
let p3 = Promise.resolve(new Promise((resolve, reject) => {
reject('err');
}));
console.log(p1,p2,p3);
</script>
复制代码
四、reject方法的实现
该方法总是返回一个失败的Promise
代码:
Promise.reject = function(reason) {
return new Promise(reject => {
reject(reason);
})
}
复制代码
测试:
<script>
let p1 = Promise.reject('err');
let p2 = Promise.reject(new Promise(resolve,reject) => {
resolve('ok');
})
console.log(p1,p2);
</script>
复制代码
五、all方法的实现
该方法接收一个promise数组,只有当这个数组中的所有promise成功时,才返回成功的Promise对象,但如果有一个失败,则返回其失败的Promis
代码:
Promise.all = function(promises) {
let count = 0; //来计算数组中成功promise的数量
let arr = [];
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(val => {
count++;
arr[i] = val; //此处不能使用数组的push()方法,因为当Promise中有异步执行时,会打乱顺序(如下测试中的p2,如果使用的是push方法,则会先将p3的结果存入数组,后将p2的结果存入)
if (count === promises.length)
resolve(arr);
}, rea => {
reject(rea);
});
}
});
}
复制代码
测试:
<script>
let p1 = Promise.resolve('ok');
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('okkk');
setTimeout(() => {
resolve('okkk');
}, 1000)
}));
let p3 = Promise.resolve(new Promise((resolve, reject) => {
reject('err');
// resolve('lkd');
}));
const promises = [p1, p2, p3];
let ps = Promise.all(promises)
console.log(ps)
</script>
复制代码
六、race方法的实现
该方法也需要传入一个promise数组,但它只要有一个先成功或者先失败,就返回其Promise结果
代码:
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(val => {
resolve(val);
}, rea => {
reject(rea);
});
}
});
}
复制代码
测试:
<script>
// let p1 = Promise.resolve('ok');
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// reject('err');
setTimeout(()=>{
resolve('lkd');
},1000)
}));
let p3 = Promise.reject('error');
// const promises = [p1, p2, p3];
const promises = [p2,p3]
let pn = Promise.race(promises)
console.log(pn)
</script>
复制代码
七、实现then回调的异步执行
代码:
function Promise(executor) {
function resolve(data) {
setTimeout(() => {
self.callback.forEach(item => {
item.onResolved(data)
})
})
}
function reject(data) {
setTimeout(() => {
self.callback.forEach(item => {
item.onRejected(data)
})
})
}
Promise.prototype.then = function(onResolved, onRejected) {
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
})
}
})
}
复制代码
测试:
<script>
let p = new Promise((resolve, reject) => {
resolve('ok');
console.log('111');
})
p.then(val=>{
console.log('222');
})
console.log('333');
/*
此测试如果没有实现then回调的异步执行,则会输出:
111
222
333
*/
</script>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END