Promise源码
index.html文件进行测试,Promise.js文件写源码
Promise是一个类,我们使用class进行Promise的声明
js
class Promise {}
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { resolve(1) }) console.log(p) </script>
这里还没有状态会返回一个空的Promise,里边的代码是立即同步执行的
声明resolve和reject
js,executor是立即执行函数,执行的函数时new Promise传入的函数
class Promise { constructor(executor) { // executor是一个立即执行函数,A+规范规定的名字,别的也可以 executor(1,2) // 立刻执行,执行的是我们new Promise时传入的函数 } }
html,传入resolve和reject之后,返回值是1和2
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { console.log(resolve, reject) // 1 2 }) console.log(p) </script>
成功resolve和失败两种状态已经声明完成了,但是我们传入这两种状态就会获得返回值,不会判断成功或者失败。
js
class Promise { constructor(executor) { // executor是一个立即执行函数,A+规范规定的名字,别的也可以 let resolve = (value) => { console.log('成功的信息', value) } let reject = (reason) => { console.log('失败的信息', reason) } executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数 } }
html
<script src="./Promise.js"></script>
<script>
let p = new Promise((resolve, reject) => {
console.log(resolve, reject)
resolve(1) // 成功的信息 1
reject(2) // 失败的信息 2
})
console.log(p)
</script>
处理Promise的三种状态
状态是实例独有的属性,也是不可逆转的,所以我们要进行,状态的更新,进行对应状态的赋值(更新成功或者失败之后的值)。这时这里状态只能被修改一次(pending修改状态只能修改一次叫做状态凝固),只有pending状态才可以被修改,如果不是pending状态不能被修改。
js,这里做了,添加状态更新,然后进行赋值,添加判断,是pending状态才可以进行修改
class Promise { constructor(executor) { this.status = 'pending'; // 默认状态 this.value = undefined; // 成功的值 this.reason = undefined; // 失败的原因 let resolve = (value) => { if (this.status === 'pending') { this.status = 'resolved'; // 更新状态 this.value = value; // 更新成功的值 } } let reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; // 更新状态 this.reason = reason; // 更新失败的原因 } } executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数 } }
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { resolve(1) // 成功的信息 1 reject(2) // 失败的信息 2 }) console.log(p) </script>
可以实现初步的then和catch操作
首先我们添加给原型上,不添加到实例上。添加到实例上,会浪费性能,用不用他都有,添加到原型上不会浪费性能,用的时候才有。添加then方法,传入两个参数成功状态和失败状态,进行判断,判断成功之后,执行成功的方法,传入成功的值。判断失败之后,执行失败的方法,传入失败的原因。执行传入的函数出错的时候(是真的出错了),使用try catch捕获executor函数的执行错误,return一个错误的回调reject,进行返回。
js,添加了then方法,进行状态的判断,然后进行回调。try catch捕获,传入的函数报错了,返回一个错误的回调
class Promise { constructor(executor) { this.status = 'pending'; // 默认状态 this.value = undefined; // 成功的值,给then方法中的回调函数使用 this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用 let resolve = (value) => { if (this.status === 'pending') { this.status = 'resolved'; // 更新状态 this.value = value; // 更新成功的值 } } let reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; // 更新状态 this.reason = reason; // 更新失败的原因 } } try { executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数 } catch (e) { reject(e) // 如果执行失败,就直接执行失败的逻辑 } // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能 } then(onFulfilled, onRejected) { // 这里添加给原型上 // onFulfilled => p成功后,调用的回调函数 // onRejected => p失败后,调用的回调函数 if (this.status === 'resolved') { // 判断状态成功之后 onFulfilled(this.value); // 进行成功的函数调用,传入成功的值 } if (this.status === 'rejected') { // 判断状态失败之后 onRejected(this.reason); // 进行失败的函数调用,传入失败的原因 } } }
html,可以使用.then和。catch进行初步的链式调用了
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { resolve(1) // 成功的信息 1 reject(2) // 失败的信息 2 }) // console.log(p) p.then(res => { console.log('1-' + res) }, err => { console.log('2-' + err) }) </script>
实现异步操作
当我们一秒之后,才将Promise的状态执行成成功或者失败,如果不做处理,是不会执行后边的函数的,then不会进行一个状态的判断。这里的回调,希望再Promise的状态更新程fulfiled。如果有异步的操作,不是立即满足条件的,就等条件满足之后,再来调用这个函数。then会被先执行,然后执行回调函数。
js创建一个空数组,然后进行pending状态的判断,数组添加成功的状态和成功的值,添加失败的状态和失败的值。最后在成功或者失败的状态中,进行数组循环,和方法的发布
class Promise {
constructor(executor) {
this.status = 'pending'; // 默认状态
this.value = undefined; // 成功的值,给then方法中的回调函数使用
this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'; // 更新状态
this.value = value; // 更新成功的值
this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'; // 更新状态
this.reason = reason; // 更新失败的原因
this.onRejectedCallbacks.forEach(fn => fn()); // 发布
}
}
// console.log('1s之后resolve函数执行了')
try {
executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
} catch (e) {
reject(e) // 如果执行失败,就直接执行失败的逻辑
}
// this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
}
then(onFulfilled, onRejected) { // 这里添加给原型上
// onFulfilled => p成功后,调用的回调函数
// onRejected => p失败后,调用的回调函数
if (this.status === 'resolved') { // 判断状态成功之后
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
}
if (this.status === 'rejected') { // 判断状态失败之后
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
}
// console.log('then函数执行了')
if (this.status === 'pending') { // 判断状态是等待的时候
this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
});
this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
});
}
}}
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { setTimeout(() => { reject('失败') }, 1000) }) // console.log(p) p.then(res => { console.log('1-' + res) }, err => { console.log('2-' + err) }) </script>
实现链式调用
上一个.then要返回一个Promise对象,不然返回undefined是没有.then方法的
js中new了一个新的promise方法,然后进行return,新的promise中,获取上次运行的返回值,进行一个返回值的传入,传入到下一个使用
class Promise { constructor(executor) { this.status = 'pending'; // 默认状态 this.value = undefined; // 成功的值,给then方法中的回调函数使用 this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用 this.onFulfilledCallbacks = []; // 存放成功的回调函数 this.onRejectedCallbacks = []; // 存放失败的回调函数 let resolve = (value) => { if (this.status === 'pending') { this.status = 'resolved'; // 更新状态 this.value = value; // 更新成功的值 this.onFulfilledCallbacks.forEach(fn => fn()); // 发布 } } let reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; // 更新状态 this.reason = reason; // 更新失败的原因 this.onRejectedCallbacks.forEach(fn => fn()); // 发布 } } // console.log('1s之后resolve函数执行了') try { executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数 } catch (e) { reject(e) // 如果执行失败,就直接执行失败的逻辑 } // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能 } then(onFulfilled, onRejected) { // 这里添加给原型上 // onFulfilled => p成功后,调用的回调函数 // onRejected => p失败后,调用的回调函数 let promise2 = new Promise((resolve,reject)=>{ if (this.status === 'resolved') { // 判断状态成功之后 const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值 // 把我们的返回值返回 resolve(x); } if (this.status === 'rejected') { // 判断状态失败之后 const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因 // 把我们的返回值返回 reject(x); } // console.log('then函数执行了') if (this.status === 'pending') { // 判断状态是等待的时候 this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中 onFulfilled(this.value); // 进行成功的函数调用,传入成功的值 }); this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中 onRejected(this.reason); // 进行失败的函数调用,传入失败的原因 }); } }) return promise2; }}
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { // setTimeout(() => { // reject('失败') // }, 1000) resolve('成功') }) // console.log(p) p.then(res => { console.log('1-' + res) return 100 }, err => { console.log('2-' + err) }).then(res => { console.log('3-' + res) return 200 }, err => { console.log('4-' + err) }).then(res => { console.log('5-' + res) }, err => { console.log('6-' + err) }) </script>
prmoise链式调用,处理不同的状态
我们在then中return中return一个promise,我们之前获取到的x是前一个.then的返回值,我们需要对x进行分析:1,如果是普通值,直接调用resolve;2,如果是一个Promise对象,看Promise是否成功?如果成功调用resolve如果失败调用reject。推荐:对x进行判断,对x进行处理的代码封装成一个函数
js声明一个函数,进行x的判断
class Promise {
constructor(executor) {
this.status = 'pending'; // 默认状态
this.value = undefined; // 成功的值,给then方法中的回调函数使用
this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'; // 更新状态
this.value = value; // 更新成功的值
this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'; // 更新状态
this.reason = reason; // 更新失败的原因
this.onRejectedCallbacks.forEach(fn => fn()); // 发布
}
}
// console.log('1s之后resolve函数执行了')
try {
executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
} catch (e) {
reject(e) // 如果执行失败,就直接执行失败的逻辑
}
// this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
}
then(onFulfilled, onRejected) { // 这里添加给原型上
// onFulfilled => p成功后,调用的回调函数
// onRejected => p失败后,调用的回调函数
let promise2 = new Promise((resolve,reject)=>{
if (this.status === 'resolved') { // 判断状态成功之后
const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
// 把我们的返回值返回
resolvePromise(x,resolve,reject)
}
if (this.status === 'rejected') { // 判断状态失败之后
const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
// 把我们的返回值返回
reject(x);
}
// console.log('then函数执行了')
if (this.status === 'pending') { // 判断状态是等待的时候
this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
});
this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
});
}
})
return promise2;
}}
function resolvePromise(x,resolve,reject){
if (x instanceof Promise) { // 判断如果是一个promise,等他成功,等他失败
// x.then(value) => {
// resolve(value)
// },err=> {
// reject(err)
// })
x.then(resolve,reject)
} else {
resolve(x) // 如果不是promise,直接成功即可
}
}
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { // setTimeout(() => { // reject('失败') // }, 1000) resolve('成功') }) // console.log(p) p.then(res => { console.log('1-' + res) return new Promise((resolve, reject) => { resolve(100) }) }, err => { console.log('2-' + err) }).then(res => { console.log('3-' + res) return 200 }, err => { console.log('4-' + err) }).then(res => { console.log('5-' + res) }, err => { console.log('6-' + err) }) </script>
处理循环调用的问题
注意点:.then中返回的promise对象,不能是自己,我们自己写这个是正确的,官方的是错的。自己调用自己的返回值
const p1 = p.then( res => { console.log('1-' + res) return p1 }, err => { console.log('2-' + err) } ) p1.then(data => { console.log(data) })
判断Promise和x是不是同一个函数,如果是同一个函数就是错的。promise2中的代码开启异步执行,添加微任务,进行try catch捕获
js添加异步任务
class Promise { constructor(executor) { this.status = 'pending'; // 默认状态 this.value = undefined; // 成功的值,给then方法中的回调函数使用 this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用 this.onFulfilledCallbacks = []; // 存放成功的回调函数 this.onRejectedCallbacks = []; // 存放失败的回调函数 let resolve = (value) => { if (this.status === 'pending') { this.status = 'resolved'; // 更新状态 this.value = value; // 更新成功的值 this.onFulfilledCallbacks.forEach(fn => fn()); // 发布 } } let reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; // 更新状态 this.reason = reason; // 更新失败的原因 this.onRejectedCallbacks.forEach(fn => fn()); // 发布 } } // console.log('1s之后resolve函数执行了') try { executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数 } catch (e) { reject(e) // 如果执行失败,就直接执行失败的逻辑 } // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能 } then(onFulfilled, onRejected) { // 这里添加给原型上 // onFulfilled => p成功后,调用的回调函数 // onRejected => p失败后,调用的回调函数 let promise2 = new Promise((resolve,reject)=>{ if (this.status === 'resolved') { // 判断状态成功之后 try { queueMicrotask(()=>{ // 微任务 const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值 // 把我们的返回值返回 resolvePromise(x,resolve,reject,promise2) }) } catch (e) { reject(e); } } if (this.status === 'rejected') { // 判断状态失败之后 try { queueMicrotask(()=>{ // 微任务 const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因 // 把我们的返回值返回 resolvePromise(x,resolve,reject,promise2) }) } catch (e) { reject(e); } } // console.log('then函数执行了') if (this.status === 'pending') { // 判断状态是等待的时候 this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中 onFulfilled(this.value); // 进行成功的函数调用,传入成功的值 }); this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中 onRejected(this.reason); // 进行失败的函数调用,传入失败的原因 }); } }) return promise2; }} function resolvePromise(x,resolve,reject,promise2){ // 处理循环调用 if (x === promise2) { console.error('循环引用') return reject(new TypeError('循环引用')) } if (x instanceof Promise) { // 判断如果是一个promise,等他成功,等他失败 // x.then(value) => { // resolve(value) // },err=> { // reject(err) // }) x.then(resolve,reject) } else { resolve(x) // 如果不是promise,直接成功即可 } }
html
<script src="./Promise.js"></script> <script> let p = new Promise((resolve, reject) => { // setTimeout(() => { // reject('失败') // }, 1000) resolve('成功') }) console.log(p) // p.then(res => { // console.log('1-' + res) // return new Promise((resolve, reject) => { // resolve(100) // }) // }, err => { // console.log('2-' + err) // }).then(res => { // console.log('3-' + res) // return 200 // }, err => { // console.log('4-' + err) // }).then(res => { // console.log('5-' + res) // }, err => { // console.log('6-' + err) // }) const p1 = p.then( res => { console.log('1-' + res) return p1 }, err => { console.log('2-' + err) } ) </script>
标签:status,resolve,静态方法,log,源码,Promise,reject,console From: https://www.cnblogs.com/hgng/p/17252996.html