这下要搞的东西就有点嗯,不过脑子的感觉,难度蹭的一下就提高了,头疼啊。其实就是考虑then
函数到底要做什么。then
就是然后的意思嘛,描述起来就是当成功的时候要做什么,当失败的时候要做什么。那这时马上做吗?不一定。
js
p.then(
(value) => {
console.log("成功的回调函数");
},
(reason) => {
console.log('失败的回调函数');
}
);
就算是then
函数要立刻去执行里面的函数,那是不是一定要放到微队列里边?
如何来产生一个微队列呢?
js
function runMicroTask(callback) {
// node environments
if (process && process.nextTick) {
process.nextTick(callback);
} else if (MutationObserver) {
const a = document.createElement("span");
new MutationObserver(callback).observe(a, {
attributes: true,
});
a.innerHTML = 1;
} else {
setTimeout(callback, 0);
}
}
这就算是简单的产生了一个微队列了,node
环境通过process.nextTick
来执行微队列。浏览器
通过MutationObserver
来执行微队列。
好了,下面就来实现一下then
函数,只能实现个大概啊,毕竟then
函数还是很复杂的。在写then
函数的时候,思考下它有什么样的参数传入,有什么样的返回值。
看了promise
,知道需要两个参数,一个是成功之后要做的事,一个是失败之后要做的事。
js
/**
* @description: then 成功或失败要做的事 满足 Promise A+ 规范
* @param {* Function} onFulfilled 成功的回调
* @param {* Function} onRejected 失败的回调
* @return {* Object} Object 返回一个新的Promise
*/
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {});
}
then
函数不是马上执行,也不是马上把它放到微队列,是要等状态确定了之后才执行。
那then
函数具体要做的事就是把函数放入一个队列。相当于是一个数组,调用一次then
就放入一个函数,但不执行。再调用一次then
,再放入一个函数... 等到将来状态确定了之后,再从头到尾依次去执行这些函数。所以我们的myPromise
需要一个队列来存放这些函数。那then
理解起来就变得简单了,就是把函数放入队列。
js
this._handler = []; //处理函数形成的队列
当调用then
的时候,就把函数放进去。但是当所有函数放完了,将来状态改变,从头到尾依次执行函数的时候,并不知道这个函数是成功的还是失败的,所以得给这些函数标记个属性。所以抽离一个函数去做这些标记。
js
/**
* @description: 向处理队列中添加一个函数,并标记类型
* @param {Function} excutor 需要存入的函数
* @param {String} state 该函数什么状态下执行
* @return {*}
*/
_pushHandler(excutor, state) {
this._handler.push({
excutor,
state,
});
}
/**
* @description: then 成功或失败要做的事 满足 Promise A+ 规范
* @param {Function} onFulfilled 成功的回调
* @param {Function} onRejected 失败的回调
* @return {Object} Object 返回一个新的Promise
*/
then(onFulfilled, onRejected) {
this._pushHandler(onFulfilled, FULFILLED);
this._pushHandler(onRejected, REJECTED);
return new myPromise((resolve, reject) => {});
}
现在then
函数返回了一个myPromise
,那里面的resolve
和reject
什么时候执行呢?一定是要等将来队列里函数执行的时候再去调用,比如说,
这个函数执行没有问题,那就说明了then
返回的那个myPromise
是成功的,所以此时调用resolve
,同理reject
也是一样。
因此,只有当队列里函数执行的时候,才能确定then
返回的myPromise
是成功的还是失败的。
那如何去获取这个resolve
和reject
呢?
传给队列处理函数
,等将来函数执行了,就按条件执行resolve
或reject
。
js
/**
* @description: 向处理队列中添加一个函数,并标记类型
* @param {Function} excutor 需要存入的函数
* @param {String} state 该函数什么状态下执行
* @param {Function} resolve 让then函数返回的 promise 成功
* @param {Function} reject 让then函数返回的 promise 失败
* @return {*}
*/
_pushHandler(excutor, state, resolve, reject) {
this._handler.push({
excutor,
state,
resolve,
reject,
});
}
/**
* @description: then 成功或失败要做的事 满足 Promise A+ 规范
* @param {Function} onFulfilled 成功的回调
* @param {Function} onRejected 失败的回调
* @return {Object} Object 返回一个新的Promise
*/
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
this._pushHandler(onFulfilled, FULFILLED, resolve, reject);
this._pushHandler(onRejected, REJECTED,resolve, reject);
});
}
现在来调用看看。
js
p.then(
function A1() {},
function A2() {}
);
p.then(
function B1() {},
function B2() {}
);
总共传了4个函数,那这4个函数都被放到队列里了。
那等将来这个excutor
函数成功执行,那就调用resolve
,让then
返回的myPromise
成功。