2019-06-16 手写简易promise(妙味王允)
2019-06-16 本文已影响0人
DreamNeverDie
customPromise.js
;(function(){
const status = {
pending: 0,
fulfilled: 1,
rejected: 2
}
class CustomePromise{
constructor(func){
// 初始状态
this._status = status.pending;
this._value = null; // 记录resolve函数传入的参数
this._error = null; // 记录reject函数传入的参数
// 收集成功状态要执行的函数
this.resolvedArr = [];
// 收集失败状态要执行的函数
this.rejectedArr = [];
this._handler(func)
}
// 判断value有没有then函数,并且拿出then函数
_getThen(value){
let type = typeof value;
if(value && (type === 'object' || type === 'function')){
let then;
if(then = value.then){
return then;
}
}
return null;
}
// 接收外部传入的函数,调用外部传入的函数
_handler(func){
let done = false; // 就是让函数值执行一次
func((value) => {
if(done) return;
done = true;
// value有没有then函数
let then = this._getThen(value);
if(then){
// 拿到对象的then之后,怎么知道这个promise对象完成了呢?
// 在then函数上注册成功和失败函数就可以
return this._handler(then.bind(value))
}
this._resolve(value);
},(error) => {
if(done) return;
done = true;
// value有没有then函数
let then = this._getThen(error);
if(then){
// 拿到对象的then之后,怎么知道这个promise对象完成了呢?
// 在then函数上注册成功和失败函数就可以
return this._handler(then.bind(error))
}
this._reject(error);
});
}
_resolve(value){
setTimeout(() => {
// 把状态改为成功
this._status = status.fulfilled;
this._value = value;
// 执行所有成功的函数
this.resolvedArr.forEach(item => {
item(this._value)
})
})
}
_reject(error){
setTimeout(() => {
// 把状态改为失败
this._status = status.rejected;
this._error = error;
this.rejectedArr.forEach(item => item(this._error));
})
}
// 收集注册的成功状态或失败状态要执行的函数
_done(resolvedFunc,rejectedFunc){
//pending的时候收集
resolvedFunc = typeof resolvedFunc === 'function'
? resolvedFunc : null;
rejectedFunc = typeof rejectedFunc === 'function'
? rejectedFunc : null;
// 收集
if(this._status === 0){
if(resolvedFunc) this.resolvedArr.push(resolvedFunc);
if(rejectedFunc) this.rejectedArr.push(rejectedFunc);
}else if(this._status === 1 && resolvedFunc){ // 直接执行
resolvedFunc(this._value);
}else if(this._status === 2 && rejectedFunc){
rejectedFunc(this._error);
}
}
// 收集注册的成功状态或失败状态要执行的函数
// 返回一个promise对象
then(resolvedFunc,rejectedFunc){
//this._done(resolvedFunc,rejectedFunc)
return new CustomePromise((resolve,reject) => {
this._done(
(value) => {
// resolvedFunc不是一个函数
if(typeof resolvedFunc !== 'function'){
return resolve(value);
}
resolve(resolvedFunc(value));
},
(error) => {
if(typeof rejectedFunc !== 'function'){
return reject(error);
}
reject(rejectedFunc(error))
}
)
})
}
}
window.CustomePromise = CustomePromise;
})();
使用自己写的CustomePromise
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style>
</style>
<script src="./customePromise.js"></script>
<script>
// new Promise返回的对象称之为Promise对象
/*
三种状态:
pending 正在进行
fulfilled 已完成
rejected 已失败
1. new Promise 接收一个函数 executor
2. 函数 executor 接收两个参数,resolve,reject
调用resolve的时候,把promise对象转成成功状态
调用reject的时候,把promise对象转成失败状态
3. promise对象的then方法来注册成功状态或者失败状态要执行的函数
p.then(resolveFunc,rejectFunc);
p.then(resolveFunc,rejectFunc);
p.then(resolveFunc,rejectFunc);
p.then(resolveFunc,rejectFunc);
实现是一个promise对象调用多次then方法
5. then函数的链式操作
p.then().then().then();
就是then函数执行后返回一个promise对象
6. thenable
拥有 then 方法的对象或函数
{
then(){}
}
promise对象也拥有then方法
7. 当给resolve传入一个promise对象的时候,只有等到promise对象装成成功或者失败,resolve才会成功
8.resovle要接受的参数
1. 简单值
2. 接收thenable对象
9.then中成功或失败执行的函数的返回值
1. 有简单类型返回值,作为then方法返回的promise对象的成功状态的值
2. 当返回一个thenable对象的时候,只有是成功状态才能执行下一个then
*/
let p = new CustomePromise((resolve,reject) => {
setTimeout(function (){
resolve('成功');
},1000)
});
p.then((data) => {
console.log('第一个then成功',data)
return new Promise((resolve) => {
setTimeout(() => {
resolve('延迟了5000')
},5000)
})
}).then((data) => {
console.log('第2个then',data)
})
.then(123)
.then((data) => {
console.log('第4个then',data)
});
</script>
</head>
<body>
</body>
</html>