手写promise,重点理清思路,步步为营。以下,请实操!
声明一个叫promise类,难度1颗星
已知:promise是个类,其参数是一个函数,专业名词是executor,executor立即执行
实战,自己来个promise类让hi成功打印!
let p = new Promise(() => {
// 就这行执行
console.log('hi')
});
console.log(p);
答案的分割线,hi!,这个难住的话,就不用往下看了,ha sa ki !!!
揭晓答案:
class Promise {
constructor(executor) {
executor();
}
}
加入resolve和reject,难度2颗星
再已知:executor里面有两个参数,一个叫resolve,一个叫reject。因为使用的时候,直接用,所以内部必然已经定义了resolve和reject,再传入到executor。
实战:让resolve或者reject能执行!
let p = new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
// 这个执行
resolve();
} else {
// 或这个执行
reject();
}
});
console.log(p);
答案的分割线,hi!,这个难住的话,看了下面 再想想 !!!
揭晓答案:
class Promise {
constructor(executor) {
const resolve = () => {
console.log(1);
};
const reject = () => {
console.log(0);
};
executor(resolve, reject);
}
}
let p = new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve();
} else {
reject();
}
});
console.log(p);
加入状态,难度3颗星
再已知:
- promise有 状态 和 value或reason,初始状态是pending,初始的value和reason都是undefined
- promise一共三种状态:pending/fulfilled/rejected
- 初始状态是pending,随着程序的运行,其可以转变为fulfilled 或 rejected,但只能转变一次
- fulfilled的时候,状态不能再改变,且必须有一个不可改变的值(value),可以是undefined
- rejected的时候,状态不能再改变,且必须有一个不可改变的原因(reason),可以是undefined
- resolve函数可以将promise的state变成fulfilled,value任意传入的
- reject函数可以将promise的state变成rejected,reason任意传入的
- 若executor函数报错,直接执行reject()
- 这里反向推导,想要状态变化必须执行resolve或者reject
实战:让p是个有状态有值的!不是pending的那种!
let p = new Promise((resolve, reject) => {
// 如果这里报错直接变成rejected,reason就是e
// console(1);
if (Math.random() > 0.5) {
resolve(1);
// 状态已定,这里其实永远不会执行
console(1);
} else {
reject(0);
}
// 状态已定,这里其实永远不会执行
resolve(2);
});
// !!!让p必须有最终的状态和value/reason
console.log(p);
答案的分割线,hi!,这个难住的话,看了下面 再想想 !!!
揭晓答案:
class Promise {
constructor(executor) {
// 定义三种状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
const resolve = value => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的值和状态
this.value = value;
this.state = FULFILLED;
console.log(value);
};
const reject = reason => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的reason和状态
this.reason = reason;
this.state = REJECTED;
console.log(reason);
};
// 定义 初始状态/value/reason
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
// 注意executor执行的时候,若报错,则直接reject
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
}
let p = new Promise((resolve, reject) => {
// 如果这里报错直接变成rejected,reason就是e
// console(1);
if (Math.random() > 0.5) {
resolve(1);
// 状态已定,这里其实永远不会执行
console(1);
} else {
reject(0);
}
// 状态已定,这里其实永远不会执行
resolve(2);
});
console.log(p);
加入then,难度2颗星
再已知:
- Promise有一个叫做then的方法,里面有两个参数:onFulfilled,onRejected
- 当promise的状态是fulfilled,则执行onFulfilled,传入this.value。为rejected的时候,则执行onRejected,传入this.reason
实战:让log打印出来then和value
let p = new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve(1);
} else {
reject(0);
}
});
p.then(
value => {
// 让这行执行
console.log("then", value);
},
reason => {
// 或让这行执行
console.log("then", reason);
}
);
console.log(p);
答案的分割线,hi!,这个难住的话,看了下面 再想想 !!!
揭晓答案:
// 定义三种状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise {
constructor(executor) {
const resolve = value => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的值和状态
this.value = value;
this.state = FULFILLED;
};
const reject = reason => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的reason和状态
this.reason = reason;
this.state = REJECTED;
};
// 定义 初始状态/value/reason
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
// 注意executor执行的时候,若报错,则直接reject
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
if (this.state === FULFILLED) {
onFulfilled(this.value);
}
if (this.state === REJECTED) {
onRejected(this.reason);
}
}
}
加入异步的处理,难度3颗星
其实到这里,如果promise中没有异步的操作,那上面就够用了。 然而!!!promise就是为了解决异步而存在的。。。。。
也就是加个setTimeout,一切就归零了,这里then那边不会执行,因为还是pending呢。
继续,再已知:
- 这里加个观察者模式。
- then的时候,将onFulfilled或onRejected加入到观察者队列。
- 状态变化的时候,也就是执行resolve或reject的时候,让相应的观察者做出行动。
实战:来!再让log打印出来then和value,你可以!来战!
let p = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve(1);
} else {
reject(0);
}
}, 200);
});
p.then(
value => {
// 对,让这行执行
console.log("then", value);
},
reason => {
// 或者这行
console.log("then", reason);
}
);
console.log(p);
答案的分割线,hi!,这个难住的话,看了下面 再想想 !!!
揭晓答案:
// 定义三种状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise {
constructor(executor) {
const resolve = value => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的值和状态
this.value = value;
this.state = FULFILLED;
// 状态变化,触发观察者行动
this.onFulfilledCallbacks.forEach(fn => {
fn(this.value);
});
};
const reject = reason => {
// 状态已定,就不做操作了
if (this.state !== PENDING) {
return;
}
// promise的reason和状态
this.reason = reason;
this.state = REJECTED;
// 状态变化,触发观察者行动
this.onRejectedCallbacks.forEach(fn => {
fn(this.reason);
});
};
// 定义 初始状态/value/reason
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
// 异步的话,就用到观察者模式,先存起来,遇到情况再执行
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// 注意executor执行的时候,若报错,则直接reject
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
if (this.state === FULFILLED) {
onFulfilled(this.value);
}
if (this.state === REJECTED) {
onRejected(this.reason);
}
// 如果是pending,那就说明有异步,加入到观察者队列!
if (this.state === PENDING) {
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
}
}
let p = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve(1);
} else {
reject(0);
}
}, 200);
});
p.then(
value => {
console.log("then", value);
},
reason => {
console.log("then", reason);
}
);
console.log(p);
加入链式的处理,难度5颗星
我还不会!哈哈哈!回头会了补上!