const PENDING = Symbol('PENDING');
const FULFILLED = Symbol('FULFILLED');
const REJECTED = Symbol('REJECTED');
class MyPromise {
constructor(fn) {}
then(successFn, failFn) {}
catch(failFn) {}
finally(finalFn){}
static resolve(val) {}
static reject(val) {}
static all(promiseArr) {}
static race(promiseArr) {}
}
Promise 内部维护着三种状态 pending、fulfilled 和 rejected,状态只能从 pending 转变到 fulfilled,或从 pending 转变到 rejected 且该转变不可逆。Promise 主要提供了三个实例方法 then,catch,finally,和4个静态方法 resolve,reject,all,race。所有方法都都返回一个Promise对象。
constructor(fn) {
this.fulfilledQueue = [];
this.rejectedQueue = [];
this._status = PENDING;
this._value = null;
// 执行成功队列中的回调函数
const handleFulfilledQueue = () => {
while(this.fulfilledQueue.length) {
let fulfiledFn = this.fulfilledQueue.shift();
fulfiledFn(this._value);
};
};
// 执行失败队列中的回调函数
const handleRejectedQueue = () => {
while(this.rejectedQueue.length) {
let rejectedFn = this.rejectedQueue.shift();
rejectedFn(this._value);
};
};
// 完成状态转变,执行回调队列中的回调函数
const _resolve = (val) => {
const fn = () => {
if(this._status !== PENDING) {
return;
}
if(val instanceof MyPromise) {
val.then((res) => {
this._status = FULFILLED;
this._value = res;
handleFulfilledQueue();
}, (err) => {
this._status = REJECTED;
this._value = err;
handleRejectedQueue();
});
} else {
this._status = FULFILLED;
this._value = val;
handleFulfilledQueue();
}
}
// 保证promise 回调函数一定是在同步任务之后执行;
setTimeout(fn, 0);
}
// 完成状态Pending到REJECTED的转变,执行rejected队列中的回调函数
const _reject = (val) => {
const fn = () => {
if(this._status !== PENDING) {
return;
}
this._status = REJECTED;
this._value = val;
handleRejectedQueue();
}
setTimeout(fn, 0);
}
try { // 处理外部传入函数执行异常
fn(_resolve, _reject);
} catch(e) {
return _reject(e);
}
}
Promise 构造函数接收一个函数执行器作为参数,该执行器的两个参数 _resolve、_reject均为函数类型,由 Promise 内部实现。执行器在 Promise 构造函数中被立即执行。
注意: MyPromise 使用 Timeout 实现异步,使得 MyPromise 只能添加 macrotask,实际上原生的Promise 是 microtask
then(successFn, failFn) {
return new MyPromise((resolve, reject) => {
// 执行成功时的回调函数
const handleSucess = (fn) => {
try {
if(typeof fn === 'function') {
const res = fn(this._value);
if(res instanceof MyPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
} else {
resolve(this._value)
}
} catch(e){
reject(e);
}
}
// 执行失败时的回调函数
const handleFail = (fn) => {
try {
if(typeof fn === 'function') {
const res = fn(this._value);
if(res instanceof MyPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
} else {
reject(this._value);
}
} catch(e) {
reject(e);
}
}
switch(this._status){
case PENDING: // 异步任务尚未完成,将回调函数推入相应队列
this.fulfilledQueue.push(() => {
handleSucess(successFn);
});
this.rejectedQueue.push(() => {
handleFail(failFn);
});
break;
case FULFILLED: // 异步任务成功完成,执行成功回调函数
handleSucess(successFn);
break;
case REJECTED: // 异步任务已失败,执行失败回调函数
handleFail(failFn);
break;
default:
console.log('Promise error status:', this._status);
break;
};
});
}
then 方法是 Promise 的一个主要方法,catch 和 finally 都可以用 then 来实现。当 Promise 的状态已经流转时,回调函数会立即被执行,当 Promise 还处于 Pending 状态时,回调函数被推入相应队列中等待执行。
class MyPromise {
constructor(fn) {
this.fulfilledQueue = [];
this.rejectedQueue = [];
this._status = PENDING;
this._value = null;
const handleFulfilledQueue = () => {
while(this.fulfilledQueue.length) {
let fulfiledFn = this.fulfilledQueue.shift();
fulfiledFn(this._value);
};
};
const handleRejectedQueue = () => {
console.log(this.rejectedQueue);
while(this.rejectedQueue.length) {
let rejectedFn = this.rejectedQueue.shift();
rejectedFn(this._value);
};
};
// 完成状态转变,执行回调队列中的回调函数
const _resolve = (val) => {
const fn = () => {
if(this._status !== PENDING) {
return;
}
if(val instanceof MyPromise) {
val.then((res) => {
this._status = FULFILLED;
this._value = res;
handleFulfilledQueue();
}, (err) => {
this._status = REJECTED;
this._value = err;
handleRejectedQueue();
});
} else {
this._status = FULFILLED;
this._value = val;
handleFulfilledQueue();
}
}
setTimeout(fn, 0);
}
// 完成状态Pending到REJECTED的转变,执行rejected队列中的回调函数
const _reject = (val) => {
const fn = () => {
if(this._status !== PENDING) {
return;
}
this._status = REJECTED;
this._value = val;
handleRejectedQueue();
}
setTimeout(fn, 0);
}
try { // 处理外部传入函数执行异常
fn(_resolve, _reject);
} catch(e) {
return _reject(e);
}
}
then(successFn, failFn) {
return new MyPromise((resolve, reject) => {
// 执行成功时的回调函数
const handleSucess = (fn) => {
try {
if(typeof fn === 'function') {
const res = fn(this._value);
if(res instanceof MyPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
} else {
resolve(this._value)
}
} catch(e){
reject(e);
}
}
// 执行失败时的回调函数
const handleFail = (fn) => {
try {
if(typeof fn === 'function') {
const res = fn(this._value);
if(res instanceof MyPromise) {
res.then(resolve, reject);
} else {
resolve(res);
}
} else {
reject(this._value);
}
} catch(e) {
reject(e);
}
}
switch(this._status){
case PENDING: // 异步任务尚未完成,将回调函数推入相应队列
this.fulfilledQueue.push(() => {
handleSucess(successFn);
});
this.rejectedQueue.push(() => {
handleFail(failFn);
});
break;
case FULFILLED: // 异步任务成功完成,执行成功回调函数
handleSucess(successFn);
break;
case REJECTED: // 异步任务已失败,执行失败回调函数
handleFail(failFn);
break;
default:
console.log('Promise error status:', this._status);
break;
};
});
}
catch(failFn) {
return this.then(null, failFn);
}
finally(finalFn){
return this.then(finalFn, finalFn);
}
static resolve(val) {
if(val instanceof MyPromise) {
return val;
} else {
return new MyPromise((resolve, reject) =>{
resolve(val);
});
}
}
static reject(val) {
return new MyPromise((resolve, reject) => {
reject(val);
});
}
static all(promiseArr) {
return new Promise((resolve, reject) =>{
const len = promiseArr.length;
let count = 0;
let result = [];
for(let i = 0; i < len; i++) {
promiseArr[i].then((val) => {
count++;
result.push[val];
if(count === len){
resolve(result);
}
}, (err) => {
reject(err);
});
}
});
}
static race(promiseArr) {
return new Promise((resolve, reject) =>{
const len = promiseArr.length;
for(let i = 0; i < len; i++) {
promiseArr[i].then((val) => {
resolve(val);
}, (err) => {
reject(err);
});
}
});
}
}
Promise 想必大家十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对几道。
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定.
Async/Await替代Promise的6个理由:Async/Await是近年来JavaScript添加的最革命性的的特性之一。它会让你发现Promise的语法有多糟糕,而且提供了一个直观的替代方法。
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,Promise 是一个构造函数, new Promise 返回一个 promise对象 接收一个excutor执行函数作为参数
这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。和原生 Promise的调用方法一样,支持链式调用,本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。
在对数组进行一些遍历操作时,发现有些遍历方法对Promise的反馈并不是我们想要的结果。async/await为Promise的语法糖,文中会直接使用async/await替换Promise;map可以说是对Promise最友好的一个函数了,
最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到。在axios整体配置的代码中,过滤http code时,调用了filter401()、filter500(),但是这里注意并未将两个filter函数的结果返回,也就是并未返回promise,这就是导致问题出现的原因
想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行
你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve
Promise的一些用法在此不多赘述,本篇主要带领你手写一个Promise源码,学完你就会发现:Promise没有你想象中的那么难.本篇大概分为以下步骤:实现简单的同步Promise、增加异步功能、增加链式调用then、增加catch finally方法、增加all race 等方法、实现一个promise的延迟对象defer、最终测试
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!