手写Promise实现过程
1、实现Promise的核心功能
3、then方法多次调用的情况
4、then方法的链式调用,以及如何把then方法的返回值传递到下一个then方法中,再判断返回值是普通值还是peomise对象进而进一步处理
5、判断then方法返回的对象是否和该then方法的promise对象是否相同
6、捕获错误:执行器中捕获,成功、失败、等待下回调函数中捕获错误
7、then方法的参数变成可传参数
8、Prmomise.all()方法
9、Prmomise.resolve() 方法
10、finally方法
11、catch方法
// 定义好MyPromise的三种状态,用三个常量来接收
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
// MyPromise接收一个参数,这个参数是构造器函数,并且在创建MyPromise的实例对象时,这个构造器函数会立即执行
constructor(executor) {
// 构造器函数接受两个参数:resolve、reject这两个方法
// 捕获执行器错误
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// MyPromise 有三种状态 分别是:pending、fulfilled、rejected,一开始是pending状态
status = PENDING
value = undefined // resolve传递的值
reason = undefined// reject传递的错误信息
// successCallBack = undefined
successCallBack = [] // then方法多次调用时且执行器里面是异步时需将then方法里面的回调函数依此存储在该数组中
// failCallBack = undefined
failCallBack = [] // 同上
resolve = (val) => {
if (this.status !== PENDING) return // 如果不是pending 状态则阻止往下执行,因为状态一旦改变,便不可更改
// 执行resolve方法时 状态status修改为fulfilled
this.status = FULFILLED
// 将成功调用传递的值传给this.value保存起来方便后续使用
this.value = val
// 判断下this.successCallBack是否存在,如果存在则调用
// this.successCallBack && this.successCallBack(this.value)
// 从this.successCallBack中一个个取出成功回调函数调用并从数组中删除
// for (let i = this.successCallBack.length; i > 0; i--) {
// // this.successCallBack.shift()(this.value)
// this.successCallBack.shift()()
// }
while(this.successCallBack.length) this.successCallBack.shift()()
}
reject = (reason) => {
if (this.status !== PENDING) return
// 执行resolve方法时 状态status修改为rejected
this.status = REJECTED
// 将成功调用传递的值传给this.value保存起来方便后续使用
this.reason = reason
// 同理,同上
// this.failCallBack && this.failCallBack(this.reason)
// 同上
// for (let i = this.failCallBack.length; i > 0; i--) {
// // this.failCallBack.shift()(this.reason)
// this.failCallBack.shift()()
// }
while(this.failCallBack.length) this.failCallBack.shift()()
}
then(successCallBack, failCallBack) {
/****then方法不传递回调函数时 */
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
/***then方法实现链式调用 */
// 能够让then方法实现链式调用,说明then方法返回的还是一个 Promise对象,我们现在就再创建个 Promise对象 promise2,并将其返回
let promise2 = new MyPromise((resolve, reject) => {
/**** then方法里面的回调函数仍需要立即执行,所以我们将他们放在 promise2的执行器函数中*/
// 根据status的状态判断该调用哪个回调函数,fulfilled则调用成功回调函数,rejected则调用failCallBack回调函数
if (this.status === FULFILLED) {
// then方法返回的 promise2需要执行 resolve 方法将当前 then方法回调函数的返回值传递给下一个then方法的回调函数中
setTimeout(() => {
// 捕获回调函数错误
try {
let x = successCallBack(this.value)
// 需要判断下 x 是普通值还是promise对象,
// 如果是普通值直接调用resolve方法,
// 如果是 Promise对象则需要查看promise对象返回的结果
// 再根据promise对象返回的结果,决定调用resolve 还是reject
// 此时还获取不到promise2, 因为promise2需要等到new MyPromise执行完毕之后才会获取到,需加个异步代码
newPromise(promise2, x, resolve, reject) // 将then方法返回的promise对象promise2也传递过去用于判断 then方法return的x是否相同
} catch(e) {
reject(e)
}
}, 0);
// resolve(x)
// 调用成功回调函数,并传递成功时的值
//successCallBack(this.value) // then方法被多次调用时,同步情况无需处理,直接调用即可
} else if(this.status === REJECTED) {
// 调用失败回调函数,并传递失败的原因
//failCallBack(this.reason) // 同上
setTimeout(() => {
try {
let x = failCallBack(this.reason)
newPromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0);
} else { // 当执行器中时异步代码时并没有立即调用resolve 或reject,所以status状态既不是fulfilled也不是 rejected,而是还处于pending状态
// this.successCallBack = successCallBack
// 此时将then的回调函数存起来当status状态改变后再去调用回调函数
// this.successCallBack.push(successCallBack)
// 捕获错误
this.successCallBack.push(() =>{
setTimeout(() => {
try {
let x = successCallBack(this.value)
newPromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0);
})
// this.failCallBack = failCallBack
// this.failCallBack.push(failCallBack)
this.failCallBack.push(() => {
setTimeout(() => {
try {
let x = failCallBack(this.reason)
newPromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0);
})
}
})
return promise2;
}
/***finally 无论该Promise对象是成功还是失败都会执行 接受一个回调函数作为参数 */
finally(callBack) {
// finally最终返回Promise对象,而then方法返回的就时Promise对象
return this.then(value => {
return MyPromise.resolve(callBack()).then(() => value);
}, reason => {
return MyPromise.resolve(callBack()).then(() => { throw reason })
})
}
/****catch方法 */
catch (failCallBack) {
return this.then(undefined, failCallBack)
}
// 静态方法all,接受参数是一个数组
static all(arr) {
// all方法的then方法的回调返回值是一个数组,定义一个数组来接收
let result = []
let index = 0
// 返回值是一个peomise对象
return new MyPromise((resolve, reject) => {
function addData(k, v) {
result[k] = v
index++
if (index === result.length) {
resolve(result)
}
}
for(let i=0; i<arr.length; i++) {
let current = arr[i]
if(current instanceof MyPromise) {
current.then(res => {
addData(i, res)
}, reason => reject(reason))
} else {
addData(i, arr[i])
}
}
})
}
/** 静态方法 resolve,返回值是一个Promise对象,接受一个参数,当这个参数是Promise对象时
* 就将该对象作为 resolve方法的返回值,如果是个普通值,则将该值包裹在一个Promise对象中作为
* resolve方法的返回值
*/
static resolve(value) {
if (value instanceof MyPromise) return value
return new MyPromise((resolve) => resolve(value))
}
}
function newPromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('循环返回相同的peomise对象')) //加return 阻止代码往下进行
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
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、最终测试
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!