Promise源码解密-Promise A+标准

promise 的 then 方法接受两个函数参数:

promise.then(onFulfilled, onRejected)

then((res) => {

console.log(res,“res”)

}, (error) => {

console.log(error,‘reason’)

})

2.1 onFulfilledonRejected 都是可选参数。
  • 如果 onFulfilled 不是函数,必须被忽略

  • 如果 onRejected 不是函数,必须被忽略

2.2 onFulfilled

如果 onFulfilled 是函数:

  • promise 执行结束后其必须被调用,其第一个参数为 promise的value

  • promise 执行结束前其不可被调用

  • 其调用次数不可超过一次

new Promise((resolve, reject) => {

resolve(123)

}).then(result => {

console.log(result);

}, error => {

console.log(error);

});

// 这里resolve执行结束才会执行then,这里的result就是终值

2.3 onRejected

如果 onRejected 是函数:

  • promise 被拒绝执行后其必须被调用,其第一个参数为 promise 的reason

  • promise 被拒绝执行前其不可被调用

  • 其调用次数不可超过一次

2.4 调用时机

onFulfilledonRejected 只有在执行环境堆栈仅包含平台代码时才可被调用 >> 注1

2.5 调用要求

onFulfilledonRejected 必须被作为函数调用(即没有 this 值)>> 注2

2.6 多次调用

then方法可以被同一个promise 调用多次

  • promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调

  • promise 被拒绝执行时,所有的 onRejected 需按照其注册顺序依次回调

new Promise.then().then()

2.7 返回

then 方法必须返回一个 promise 对象 >> 注3, 这也就是then可以被多次调用的原因。

Promise.prototype.then=function(onFulfilled, onRejected){

return new Promise()

}

promise2 = promise1.then(onFulfilled, onRejected);

  • 如果 onFulfilled 或者 onRejected 返回一个值 x ,则运行下面的 Promise 解决过程[[Resolve]](promise2, x)

promise1.then((value)=>{

return x;

}, (reason)=>{

return x

}),

// 这种情况需要处理x函数还是值还是其他情况 ,所有用到了 Promise 解决过程

// 这种情况直接

Promise.prototype.then=function(onFulfilled, onRejected){

return let promise2 = new Promise((resolve,reject)=>{

try {

let x = onFulfilled(this.value);

resolvePromise(promise2, x, resolve, reject);

} catch (e) {

reject(e);

}

})

}

  • 如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e

promise1.then((value)=>{

throw new Error()

}, (reason)=>{

throw new Error()

}),

// 这种情况直接

Promise.prototype.then=function(onFulfilled, onRejected){

return new Promise((resolve,reject)=>{

try {

// console.log(“执行 onFulfilled”);

// 这里的x是啥? 是then中回调的return的返回值

onFulfilled(this.value);

或者

onReject(this.reason)

} catch (e) {

reject(e);

}

})

}

  • 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值

promise1.then(1,2),

Promise.prototype.then=function(onFulfilled, onRejected){

if (this.status === STATUS_FULFILLED) {

return new Promise((resolve,reject)=>{

if(typeof onFulfilled !== “function” ){

resolve(onFulfilled)

}

if(typeof onRejected !== “function” ){

resolve(onRejected)

}

})

}

}

  • 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的reason

promise1.then(1,2),

Promise.prototype.then=function(onFulfilled, onRejected){

if (this.status === STATUS_PENDING) {

return new Promise((resolve,reject)=>{

reject(onRejected)

})

}

}

Promise 解决过程


Promise 解决过程是需要输入一个 promise 和一个值 x 的一个抽象的操作,称为 [[Resolve]](promise, x),如果 xthen 方法且看上去像一个 Promise ,解决程序即尝试使 promise 接受 x 的状态;否则其用 x 的值来执行 promise 。(x是返回值,请注意上面的例子)

解决过程步骤:

xpromise 相等

如果 promisex 指向同一对象,直接 throw new TypeError

let p1=new Promise(resolve=>{

resolve()

})

let p2=p1.then(data=>{

// 返回了p2

return p2

})

x 是Promise

如果 x 是一个 Promise ,则使 promise 接受 x 的状态 >>注4

  • 如果 x 处于等待, promise 需保持等待直至 x 被执行或拒绝

  • 如果 x 处于执行,用相同的值执行 promise

  • 如果 x 处于拒绝,用相同的reason拒绝 promise

x 为对象或函数

如果 x 为对象或者函数:

  • x.then 赋值给 then>> 注5

  • 如果取 x.then 的值时抛出错误 e ,则以 e 为reason拒绝 promise

  • 如果then是函数,将x作为函数的作用域this调用。传递两个回调函数作为参数,第一个参数叫做resolvePromise

,第二个参数叫做rejectPromise:

  • 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)

  • 如果 rejectPromise 以reason r 为参数被调用,则以reason r 拒绝 promise

  • 如果 resolvePromiserejectPromise 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用

  • 如果调用then方法抛出了异常e:

  • 如果 resolvePromiserejectPromise 已经被调用,则忽略之

  • 否则以 e 为reason拒绝 promise

  • 如果 then 不是函数,以 x 为参数执行 promise

  • 如果 x 不为对象或者函数,以 x 为参数执行 promise

function resolvePromise(promise2, x, resolve, reject) {

// 用来保存是否已经reject或者resolve过

let called

if (promise2 === x) {

throw new TypeError(‘Chaining cycle detected for promise’)

}

// 如果是函数或者object的话先默认是promise

if (x != null && (typeof x === ‘object’ || typeof x === ‘function’)) {

try {

let then = x.then

// 如果then是函数的话

if (typeof then === ‘function’) {

// 为啥不直接x.then()

// 因为then已经判断过是不是function,但是x.then没有判断过

// 就让then执行 第一个参数是this 后面是成功的回调 和 失败的回调

// 这里的y是啥,如果x是promsie的话,那么y就是x中的resolve/reject的值

算法刷题

大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

写在最后

最后,对所以做Java的朋友提几点建议,也是我的个人心得:

  1. 疯狂编程

  2. 学习效果可视化

  3. 写博客

  4. 阅读优秀代码

  5. 心态调整

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值