promise
promise处理异步方法,优化了之前回调低于的问题,使得可以链式调用异步方法
// 手撕promise
class MyPromise {
constructor(executor) {
// 初始化状态
this.state = PENDING;
this.value = undefined; // 成功值
this.reason = undefined; // 失败原因
this.onFulfilledCallbacks = []; // 存储成功回调
this.onRejectedCallbacks = []; // 存储失败回调
// 定义resolve函数
const resolve = (value) => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
// 执行所有成功回调
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
// 定义reject函数
const reject = (reason) => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
// 执行所有失败回调
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
// 立即执行executor函数
executor(resolve, reject);
} catch (error) {
// 如果executor执行出错,直接reject
reject(error);
}
}
then(onFulfilled, onRejected) {
// 2.2.1: onFulfilled和onRejected都是可选的参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
// 2.2.7: then方法必须返回一个新的Promise
const promise2 = new MyPromise((resolve, reject) => {
const handleFulfilled = () => {
// 2.2.4: 必须异步执行onFulfilled
queueMicrotask(() => {
try {
const x = onFulfilled(this.value);
resolve(x)
} catch (error) {
reject(error);
}
});
};
const handleRejected = () => {
// 2.2.4: 必须异步执行onRejected
queueMicrotask(() => {
try {
const x = onRejected(this.reason);
resolve(x)
} catch (error) {
reject(error);
}
});
};
if (this.state === FULFILLED) {
handleFulfilled();
} else if (this.state === REJECTED) {
handleRejected();
} else if (this.state === PENDING) {
// 状态为pending,存储回调
this.onFulfilledCallbacks.push(handleFulfilled);
this.onRejectedCallbacks.push(handleRejected);
}
});
return promise2;
}
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called = false;
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
this.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);
}
}
}
// Promise状态常量
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
module.exports = MyPromise;
// promise.all 如果成功的请求,会等都有结果了再返回;有错误的话会马上reject
// promise.allSettle 都有结果了才会返回
// promise.race 一个有结果了马上返回
async await
async await是promsie语法糖,使得代码可读性增强
// 生成器 和 自动执行器 结合
function myAsync(genFen){
return function(...args){
const gen = genFen.apply(this, args)
return new Promise((resolve, reject) => {
const step = (key, val) => {
let result = gen[key](val);
const { done, value } = result
if(done){
resolve(value)
}
return Promise.resolve(value).then(res => {
step("next", res)
}).catch(err => {
step("throw", err)
})
}
step("next")
})
}
}
// 使用示例
const asyncAdd = myAsync(function* () {
const a = yield Promise.resolve(1);
const b = yield 2; // 非 Promise 也能处理
const c = yield Promise.resolve(3);
return a + b + c;
});
asyncAdd().then(console.log); // 6