根据promise A+规范,实现一个简易promise需要考虑如下的问题:
1.状态:pending,resolve(fulfilled),rejected
2.then方法注册回调(onFulfilled,onRejected),参数可选,参数类型是函数
3.对微任务,宏任务的调用处理(setTimeout,then回调)
4.最终值
//index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>手写一个promise</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="promise.js"></script>
<script>
//目前只能实现这么简单的调用,旨在理解其中原理,实现一个符合的规范的,太难
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 0)
}).then(value => {
console.log(value)
});
</script>
</html>
//promise.js
(function(w){
//不可变的常量状态
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
class MyPromise{
constructor(fn){
this.value = null;
this.state = PENDING;
this.resolvedCallbacks = []; //异步任务队列
this.rejectedCallbacks = [];
try {
fn(this.resolve,this.reject);
} catch(e){
this.reject(e);
}
}
then = (onFulfilled,onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected =
typeof onRejected === 'function'
? onRejected
: r => {
throw r
};
if (this.state === PENDING) {
this.resolvedCallbacks.push(onFulfilled);
this.rejectedCallbacks.push(onRejected);
}
if (this.state === RESOLVED) {
onFulfilled(this.value);
}
if (this.state === REJECTED) {
onRejected(this.value);
}
}
//resolve的参数是promise对象的话,该promise对象的最终状态由then方法执行决议,否则状态直接返回fulfilled
//所有要判断value的类型
resolve = (value) => {
if(value instanceof MyPromise){
return value.then(this.resolve,this.reject);
}
//通过setTimeout控制执行顺序
setTimeout(() => {
if(this.state === PENDING){
this.state = RESOLVED;
this.value = value;
this.resolvedCallbacks.map(cb => cb(this.value));
}
},0);
}
reject = (value) => {
setTimeout(() => {
if(this.state === PENDING){
this.state = REJECTED;
this.value = value;
this.rejectedCallbacks.map(cb => cb(this.value));
}
},0);
}
}
window.MyPromise = window.MyPromise || MyPromise;
})(window);
目前暂时实现这样,后续继续更新。。。
参考:
网友评论