Skip to main content

Promise

  • 存在三个状态:padding(等待)、fulfilled(完成)、rejected(拒绝)。

    ⚠️注意:

    • padding可以转为fulfilledrejected,且不可逆。
    • fulfilled不能与rejected相互转换。

promise构造函数如何实现?


const PROMISE_TYPE = {
PADDING: 'padding',
FULFILLED: "fulfilled",
REJECTED: "rejected",
}
export class MyPromise {
constructor(exec) {
//初始化状态为padding
this.state = PROMISE_TYPE.PADDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
//设置resolve方法
const resolve = (value) => {
//只有状态为padding,才允许改变状态
if (this.state === PROMISE_TYPE.PADDING) {
this.value = value;
this.state = PROMISE_TYPE.FULFILLED;
this.onFulfilledCallbacks.forEach((fn) => fn());
}
}
//设置reject方法
const reject = (reason) => {
// //只有状态为padding,才允许改变状态
if (this.state === PROMISE_TYPE.PADDING) {
this.reason = reason;
this.state = PROMISE_TYPE.REJECTED;
this.onRejectedCallbacks.forEach((fn) => fn());
}
}
try {
exec(resolve, reject);
} catch (error) {
reject(error)
}
}
//...
}

Promise.then方法如何实现?

export class MyPromise {
constructor(exec) {
//...详情请看promise构造函数如何实现?
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;

onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }

let p2 = new MyPromise((resolve, reject) => {
//处理异步回调
if (this.state === PROMISE_TYPE.PADDING) {
//将成功回调压入成功回调栈中
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(p2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})

//将失败回调压入失败回调栈中
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(p2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
}
// 处理成功回调结果
if (this.state === PROMISE_TYPE.FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
// 处理失败回调结果
if (this.state === PROMISE_TYPE.REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
})

}
}
  • resolvePromise

    const resolvePromise = (promise2, x, resolve, reject) => {
    if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    let called;
    if ((typeof x === 'object' && x != null) || typeof x === 'function') {
    try {
    let then = x.then;
    if (typeof then === 'function') {
    then.call(x, y => {
    if (called) return;
    called = true;
    resolvePromise(promise2, y, resolve, reject);
    }, r => {
    if (called) return;
    called = true;
    reject(r);
    })
    } else {
    resolve(x);
    }
    } catch (error) {
    if (called) return;
    called = true;
    reject(error);
    }
    } else {
    resolve(x);
    }
    }