我们分步来实现promise
step1: 声明_Promise类并绑定this
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
cb(this.resolve.bind(this), this.reject.bind(this));
}
resolve(val) {
this.value = val;
this.status = 'fulfilled';
}
reject(reason) {
this.value = reason;
this.status = 'rejected';
}
}
// 测试
var test = new _Promise((resolve, reject) => {
resolve('success');
})
// _Promise {status: "fulfilled", value: "success"}
var test = new _Promise((resolve, reject) => {
resolve('success');
reject('fail');
})
// _Promise {status: "rejected", value: "fail"}
这里需要注意的一点就是,回调函数需要绑定当前的this,不然因为class内部是严格模式,如果传入的函数执行了resolve或者reject方法时,里面的this为undefined,就会报错。
我们发现,可以先执行resolve,再执行reject,不符合promise状态不可变的特性,所以进行我们的第二步修饰~
step2: 状态保护与执行者异步错误捕获
这个步骤我们做了两件事
- 当promise的状态为pending时,resolve和reject方法中才能更改状态。
- 如果cb执行过程中,出现错误,promise状态应该变成reject。所以要给cb增加try catch。
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
}
}
}
// 测试
var test = new _Promise((resolve, reject) => {
resolve('success');
reject('fail');
})
// _Promise {status: "fulfilled", value: "success"}
var test = new _Promise((resolve, reject) => {
console.log(xxxsksks);
})
// Promise {status: "rejected", value: ReferenceError: xxxsksks is not defined
// at <anonymous>:3:17
// at new _Promise (<anonymous>:6:…}
step3: Then的基础构建
- 可以通过then接收promise返回结果,类中声明then方法
- onFulfilled, onReject方法可以不传
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
this.status == 'fulfilled' && onFulfilled(this.value);
this.status == 'rejected' && onReject(this.value);
}
}
// 测试
new _Promise((resolve, reject) => {
resolve('success');
}).then(val => {
console.log(val);
})
// success
new _Promise((resolve, reject) => {
reject('fail');
}).then(val => {}, reason => {
console.log(reason);
})
// fail
new _Promise((resolve, reject) => { // 不传reject回调 不会报错
reject('fail');
}).then(val => {})
step4: 实现Then的异步操作(微任务)与异常捕获
- Then方法里的函数也可能报错,报错也要把promise变成rejected状态,也需要加try catch
- 利用setTimeout模拟微任务的执行顺序
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
setTimeout(() => { // 模拟微任务顺序
if (this.status == 'fulfilled') {
try {
onFulfilled(this.value);
} catch(e) {
onReject(e);
}
}
if (this.status == 'rejected') {
try {
onReject(this.value);
} catch(e) {
onReject(e);
}
}
})
}
}
// 测试
new _Promise((resolve, reject) => {
resolve('success');
}).then(val => { console.log(sn) }, e => console.log(e))
// ReferenceError: sn is not defined
new _Promise((resolve, reject) => {
reject('fail');
}).then(val => { }, e => console.log(sn))
// ReferenceError: sn is not defined
new _Promise((resolve, reject) => {
resolve('success');
}).then(val => { console.log(val) }, e => {})
// 1
// success
step5: _Promise的 pending 状态处理
- 如果promise不是立即返回结果,也就是.then方法执行而且状态为pending,这时候需要记录回调函数,等待resolve或者reject执行时,执行回调
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
this.thenCbQueue.map(task => { // 执行reslove时 执行成功回调
task.onFulfilled(this.value);
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
this.thenCbQueue.map(task => {
task.onReject(reason); // 执行reslove时 执行失败回调
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
setTimeout(() => {
if (this.status == 'pending') {
// 记录then方法中的回调函数 注意是一对一对的压哦
// 注意所有错误都交给reject方法 后续优化
this.thenCbQueue.push({ onFulfilled: val => {
try {
onFulfilled(val);
} catch(e) {
onReject(e);
}
}, onReject: reason => {
try {
onReject(reason);
} catch(e) {
onReject(e);
}
} });
}
if (this.status == 'fulfilled') {
try {
onFulfilled(this.value);
} catch(e) {
onReject(e);
}
}
if (this.status == 'rejected') {
try {
onReject(this.value);
} catch(e) {
onReject(e);
}
}
})
}
}
// 测试
new _Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000)
}).then(val => { console.log(cc) }, e => { console.warn(e) })
// VM8622:3 ReferenceError: cc is not defined
step6: 异步回调执行顺序跳转
- 我们希望.then的回调永远是异步的 比如以下代码,我们期望先输出2,再输出1
new _Promise((resolve, reject) => {
setTimeout(() => {
reject(1);
console.log(2);
}, 1000)
}).then(val => { console.log(val) }, e => { console.warn(e) })
ok, 来改写代码
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
setTimeout(() => {
if (this.status == 'pending') {
// 记录then方法中的回调函数 注意是一对一对的压哦
// 注意所有错误都交给reject方法 后续优化
this.thenCbQueue.push({ onFulfilled: val => {
try {
onFulfilled(val);
} catch(e) {
onReject(e);
}
}, onReject: reason => {
try {
onReject(reason);
} catch(e) {
onReject(e);
}
} });
}
if (this.status == 'fulfilled') {
try {
onFulfilled(this.value);
} catch(e) {
onReject(e);
}
}
if (this.status == 'rejected') {
try {
onReject(this.value);
} catch(e) {
onReject(e);
}
}
})
}
}
// 测试
new _Promise((resolve, reject) => {
setTimeout(() => {
reject(1);
console.log(2);
}, 1000)
}).then(val => { console.log(val) }, e => { console.warn(e) })
// 2
// 1
step7: .then().then()链式操作
- 因为每个.then都返回一个promise,我们可以用递归的方式,让.then方法返回一个新的_promsie, 新的_Promise 执行resolve或者reject方法传递上个then 的返回值
- 注意 then 返回值的promise状态默认是成功的
new _Promise((resolve, reject) => {
resolve(1)
}).then(val => {
console.log(val, '111')
return 'ys'
}).then(val => {
console.log(val, '222')
})
// Uncaught TypeError: Cannot read property 'then' of undefined
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
// 这里包了一层 _Promise
return new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
try {
// mark
let res = onFulfilled(val);
resolve(res);
} catch(e) {
onReject(e);
}
}, onReject: reason => {
try {
// mark
let res = onReject(reason);
resolve(res);
} catch(e) {
onReject(e);
}
} });
}
if (this.status == 'fulfilled') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onFulfilled(this.value);
resolve(res);
} catch(e) {
onReject(e);
}
}
if (this.status == 'rejected') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onReject(this.value);
// 注意 then返回值的promise状态默认是成功的
resolve(res);
} catch(e) {
onReject(e);
}
}
})
})
}
}
new _Promise((resolve, reject) => {
resolve(1)
}).then(val => {
console.log(val, '000')
return 'success'
}, e => {
return 'fail'
}).then(val => {
console.log(val, '111')
}, e => {
console.log('链式调用then失败?');
})
// 1 "000"
// VM15140:9 success 111
new _Promise((resolve, reject) => {
reject(1)
}).then(val => {
console.log(val, '000')
return 'success'
}, e => {
console.log(val, '111');
return 'fail'
}).then(val => {
console.log(val, '222')
}, e => {
console.log('链式调用then失败?');
})
// 1 "111"
// VM15140:9 fail 222
new _Promise((resolve, reject) => {
setTimeout(() => reject(1), 100)
}).then(val => {
console.log(val, '000')
return 'success'
}, e => {
console.log(e, '111');
return 'fail'
}).then(val => {
console.log(val, '222')
}, e => {
console.log('链式调用then失败?');
})
// 1 "111"
// VM15140:9 fail 222
step8: then()方法错误传递
- .then方法内部错误,需要下一个.then的onReject来捕捉, 修改返回的_Promise的错误处理即可
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => {}
}
if (typeof onReject !== 'function') {
onReject = () => {}
}
// 这里包了一层 _Promise
return new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
try {
// mark
let res = onFulfilled(val);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}, onReject: reason => {
try {
// mark
let res = onReject(reason);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
} });
}
if (this.status == 'fulfilled') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onFulfilled(this.value);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}
if (this.status == 'rejected') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onReject(this.value);
// 注意 then返回值的promise状态默认是成功的
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}
})
})
}
}
// 测试
new _Promise((resolve, reject) => {
setTimeout(() => resolve(1), 100)
}).then(val => {
console.log(aaa, '000')
return 'success'
}, e => {
console.log(e, '111');
return 'fail'
}).then(val => {
console.log(val, '222')
}, e => {
console.log('错了错了', e);
})
// 错了错了 ReferenceError: aaa is not defined
step9: 实现then()的穿透传递【reject穿透有问题呀】
- 如果then方法内部没有传递参数,把变量继续往下传递 return this.value
// 原生promise具有穿透的能力
new Promise((resolve, reject) => {
reject(1)
}).then().then(val => {
console.log('resolve', val)
}, e => {
console.log('reject', e);
})
// reject 1
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里包了一层 _Promise
return new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
try {
// mark
let res = onFulfilled(val);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}, onReject: reason => {
try {
// mark
let res = onReject(reason);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
} });
}
if (this.status == 'fulfilled') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onFulfilled(this.value);
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}
if (this.status == 'rejected') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onReject(this.value);
// 注意 then返回值的promise状态默认是成功的
resolve(res);
} catch(e) {
reject(e); // onReject -> reject
}
}
})
})
}
}
// 测试
new _Promise((resolve, reject) => {
reject(1)
}).then().then(val => {
console.log('resolve', val)
}, e => {
console.log('reject', e);
})
// resolve 1 我们也实现了这种穿透 但是reject 变成了 resolve ??
step7: then返回promise的处理
- 如果then返回了一个new _Promise 需要找到对它进行取值返回操作
// 原生promise具有穿透的能力
new Promise((resolve, reject) => {
resolve(1)
}).then(val => {
return new Promise(resolve => resolve(val))
}).then(val => {
console.log('resolve', val);
})
// resolve 1
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里包了一层 _Promise
return new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
try {
// mark
let res = onFulfilled(val);
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}, onReject: reason => {
try {
// mark
let res = onReject(reason);
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
} });
}
if (this.status == 'fulfilled') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onFulfilled(this.value);
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
if (this.status == 'rejected') {
try {
// 传递上一个then的返回值 不管后面有没有接收
let res = onReject(this.value);
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
})
})
}
}
// 测试
new _Promise((resolve, reject) => {
reject(1)
}).then(val => {
return new _Promise((resolve, reject) => reject(111));
}).then(val => {
console.log('resolve', val);
}, val => {
console.log('reject', val);
})
// resolve 1
new _Promise((resolve, reject) => {
reject(1)
}).then(val => {}, reason => {
return new _Promise((resolve, reject) => reject(111))
}).then(val => {
console.log('resolve', val);
}, val => {
console.log('reject', val);
})
// reject 111
new _Promise((resolve, reject) => {
setTimeout(() => reject(1), 100)
}).then(val => {}, reason => {
return new _Promise((resolve, reject) => reject(111))
}).then(val => {
console.log('resolve', val);
}, val => {
console.log('reject', val);
})
// reject 111
step10: 优化重复代码
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里包了一层 _Promise
return new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
this.parse(onFulfilled(val), resolve, reject);
}, onReject: reason => {
this.parse(onReject(reason), resolve, reject);
} });
}
if (this.status == 'fulfilled') {
this.parse(onFulfilled(this.value), resolve, reject);
}
if (this.status == 'rejected') {
this.parse(onReject(this.value), resolve, reject);
}
})
})
}
parse(res, resolve, reject) {
try {
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
}
step11: then返回类型约束(不能返回实例自身哦)
let p = new Promise((resolve, reject) => {
resolve('解决');
}).then(val => p);
// TypeError: Chaining cycle detected for promise #<Promise>
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里判断 实例调用.then不能返回自身实例
let promiseInstance = new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
// 因为setTimeout是异步的 所以可以读到实例..
this.parse(promiseInstance, onFulfilled(val), resolve, reject);
}, onReject: reason => {
this.parse(promiseInstance, onReject(reason), resolve, reject);
} });
}
if (this.status == 'fulfilled') {
this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
}
if (this.status == 'rejected') {
this.parse(promiseInstance, onReject(this.value), resolve, reject);
}
})
})
return promiseInstance;
}
parse(instance, res, resolve, reject) {
// 如果实例和.then方法返回的实例一样 报错
if (instance == res) {
throw new TypeError('Chaining cycle detected');
}
try {
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
}
// 测试
let p = new _Promise((resolve, reject) => {
resolve('解决');
}).then(val => p);
// Uncaught TypeError: Chaining cycle detected
step12: resolve,reject静态方法实现(_Promise.xxx)
// 普通值
Promise.resolve(1).then(val => console.log(val)) // 1
// promise 【我们发现后面的成功或者失败状态是依赖返回的promise的状态】
Promise.resolve(new Promise((resolve, reject) => {
resolve('成功');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// resolve: 成功
Promise.resolve(new Promise((resolve, reject) => {
reject('失败');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// reject: 失败
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里判断 实例调用.then不能返回自身实例
let promiseInstance = new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
// 因为setTimeout是异步的 所以可以读到实例..
this.parse(promiseInstance, onFulfilled(val), resolve, reject);
}, onReject: reason => {
this.parse(promiseInstance, onReject(reason), resolve, reject);
} });
}
if (this.status == 'fulfilled') {
this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
}
if (this.status == 'rejected') {
this.parse(promiseInstance, onReject(this.value), resolve, reject);
}
})
})
return promiseInstance;
}
parse(instance, res, resolve, reject) {
// 如果实例和.then方法返回的实例一样 报错
if (instance == res) {
throw new TypeError('Chaining cycle detected');
}
try {
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
// 静态方法resolve
static resolve(value) {
return new _Promise((resolve, reject) => {
if (value instanceof _Promise) {
// value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
value.then(val => resolve(val), reason => reject(reason))
} else {
resolve(value);
}
});
}
// 静态方法reject实现较为简单
static reject(value) {
return new _Promise((resolve, reject) => {
reject(value);
});
}
}
// 测试
// 普通值
_Promise.resolve(1).then(val => console.log(val)) // 1
// promsie
_Promise.resolve(new _Promise((resolve, reject) => {
resolve('成功');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// 成功
_Promise.resolve(new _Promise((resolve, reject) => {
reject('失败');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// 失败
step13: _Promise.all方法实现
Promise有以下特性:
- 接收一个iterable作为参数
- 全部成功,按传入顺序返回结果集
- 一个失败,返回失败项
- 参数列表内元素如果非promise,原样返回
// 全部成功 返回成功结果的集合
let u1 = new Promise(resolve => {
resolve('ys');
});
let u2 = new Promise(resolve => {
resolve('笑嘻嘻');
});
Promise.all([u1, u2]).then(val => {
console.log(val);
});
// ["ys", "笑嘻嘻"]
// 如果有一个失败 则返回失败项 状态为rejected
let u1 = new Promise(resolve => {
resolve('ys');
});
let u2 = new Promise((result, reject) => {
reject('哭唧唧');
});
Promise.all([u1, u2]).then(null, reason => {
console.log(reason);
});
// 哭唧唧
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里判断 实例调用.then不能返回自身实例
let promiseInstance = new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
// 因为setTimeout是异步的 所以可以读到实例..
this.parse(promiseInstance, onFulfilled(val), resolve, reject);
}, onReject: reason => {
this.parse(promiseInstance, onReject(reason), resolve, reject);
} });
}
if (this.status == 'fulfilled') {
this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
}
if (this.status == 'rejected') {
this.parse(promiseInstance, onReject(this.value), resolve, reject);
}
})
})
return promiseInstance;
}
parse(instance, res, resolve, reject) {
// 如果实例和.then方法返回的实例一样 报错
if (instance == res) {
throw new TypeError('Chaining cycle detected');
}
try {
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
// 静态方法resolve
static resolve(value) {
return new _Promise((resolve, reject) => {
if (value instanceof _Promise) {
// value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
value.then(val => resolve(val), reason => reject(reason))
} else {
resolve(value);
}
});
}
// 静态方法reject实现较为简单
static reject(value) {
return new _Promise((resolve, reject) => {
reject(value);
});
}
// 传进来的是一个promise实例列表
static all(promises) {
// if (!Array.isArray(promises)) {
// throw new Error("promises must be an iterator")
// }
// 注意 参数必须为迭代器对象
// 迭代器对象能调用...方法转为数组
// Array.form能将一个没有部署迭代器的类数组转成数组 所以不适合判断
if (typeof promises[Symbol.iterator] !== 'function') {
console.log(new TypeError('object is not iterable'));
}
return new _Promise((resolve, reject) => {
let resolvedCount = 0;
let successPromiseSet = []; // 成功的结果数组
// 迭代器对象能调用...方法转为数组 再调用forEach
Array.from(promises).forEach((promise, idx) => {
// 可能输入的不是一个promise 如果不是promise对象原样返回
// 为了兼容都能调用then方法 用resolve包一层
_Promise.resolve(promise).then(val => {
successPromiseSet[idx] = val;
resolvedCount++;
// 如果结果的数量 = 传递的promise数量 则返回结果集
resolvedCount == promises.length && resolve(successPromiseSet);
}, reason => {
reject(reason);
});
});
})
}
}
// 测试
var u1 = new _Promise(resolve => {
setTimeout(() => {
resolve('ys');
}, 200);
});
var u2 = new _Promise((resolve, reject) => {
setTimeout(() => {
resolve('笑嘻嘻');
}, 15000)
});
var u3 = new _Promise((resolve, reject) => {
setTimeout(() => {
resolve('lalal');
}, 500)
});
var u4 = 4;
// all result is : ["ys","笑嘻嘻","lalal",4]
var u1 = new _Promise(resolve => {
resolve('ys');
});
let u2 = new _Promise((resolve, reject) => {
reject('笑嘻嘻');
});
_Promise.all([u1, u2]).then(null, reason => {
console.log('reject: ' + reason);
});
// reject: 笑嘻嘻
step14: _Promise.race静态方法实现
谁快用谁,这个实现起来相当好写, 有值回来 返回即可
var u1 = new Promise(resolve => {
setTimeout(() => {
resolve('ys');
}, 2000);
});
var u2 = new Promise(resolve => {
setTimeout(() => {
resolve('笑嘻嘻');
}, 1000)
});
Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val));
// race winner is : 笑嘻嘻
// 失败状态也可以哦
var u1 = new Promise(resolve => {
setTimeout(() => {
resolve('ys');
}, 2000);
});
var u2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('笑嘻嘻');
}, 1000)
});
Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// VM117142:14 reject: race winner is : 笑嘻嘻
CODE
class _Promise {
constructor(cb) {
this.status = 'pending';
this.value = null;
this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
try {
cb(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
this.reject(e);
}
}
resolve(val) {
if (this.status == 'pending') {
this.value = val;
this.status = 'fulfilled';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onFulfilled(this.value);
});
});
}
}
reject(reason) {
if (this.status == 'pending') {
this.value = reason;
this.status = 'rejected';
setTimeout(() => { // 增加异步执行逻辑
this.thenCbQueue.map(task => {
task.onReject(reason);
});
});
}
}
then(onFulfilled, onReject) {
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value // 往下传递 被下面res接收
}
if (typeof onReject !== 'function') {
onReject = () => this.value // 往下传递 被下面res接收
}
// 这里判断 实例调用.then不能返回自身实例
let promiseInstance = new _Promise((resolve, reject) => {
setTimeout(() => {
if (this.status == 'pending') {
this.thenCbQueue.push({ onFulfilled: val => {
// 因为setTimeout是异步的 所以可以读到实例..
this.parse(promiseInstance, onFulfilled(val), resolve, reject);
}, onReject: reason => {
this.parse(promiseInstance, onReject(reason), resolve, reject);
} });
}
if (this.status == 'fulfilled') {
this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
}
if (this.status == 'rejected') {
this.parse(promiseInstance, onReject(this.value), resolve, reject);
}
})
})
return promiseInstance;
}
parse(instance, res, resolve, reject) {
// 如果实例和.then方法返回的实例一样 报错
if (instance == res) {
throw new TypeError('Chaining cycle detected');
}
try {
// 注意 then返回值的promise状态默认是成功的
if (res instanceof _Promise) {
// res 是 _Promise的实例
res.then(val => resolve(val), reason => reject(reason))
} else {
resolve(res);
}
} catch(e) {
reject(e); // onReject -> reject
}
}
// 静态方法resolve
static resolve(value) {
return new _Promise((resolve, reject) => {
if (value instanceof _Promise) {
// value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
value.then(val => resolve(val), reason => reject(reason))
} else {
resolve(value);
}
});
}
// 静态方法reject实现较为简单
static reject(value) {
return new _Promise((resolve, reject) => {
reject(value);
});
}
// 传进来的是一个promise实例列表
static all(promises) {
return new _Promise((resolve, reject) => {
const successPromiseSet = []; // 成功的结果数组
promises.forEach(promise => {
promise.then(val => {
successPromiseSet.push(val);
// 如果结果的数量 = 传递的promise数量 则返回结果集
if (successPromiseSet.length == promises.length) {
resolve(successPromiseSet);
}
}, reason => {
reject(reason);
});
});
})
}
// 传进来的也是一个promise实例列表
// promise 一个状态改变 就不能再次更改
static race(promises) {
return new _Promise((resolve, reject) => {
promises.forEach(promise => {
promise.then(val => resolve(val), reason => reject(reason));
});
});
}
}
// 测试
var u1 = new _Promise(resolve => {
setTimeout(() => {
resolve('ys');
}, 200);
});
var u2 = new _Promise((resolve, reject) => {
setTimeout(() => {
reject('笑嘻嘻');
}, 1000)
});
_Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// race winner is : ys
var u1 = new _Promise(resolve => {
setTimeout(() => {
resolve('ys');
}, 2000);
});
var u2 = new _Promise((resolve, reject) => {
setTimeout(() => {
resolve('笑嘻嘻');
}, 1000)
});
_Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// race winner is : 笑嘻嘻