手写Promise函数
Promise可以说是面试十次八次都要问的知识点,他就是一个解决异步编程的方案,可以进行优雅的链式回调。
什么叫异步编程?
网络上有很多非常解释同步异步编程的学术性话语。我个人的理解:异步编程就是一个很好的时间管理者不浪费每一秒,一直都在干活,停不下来的节奏,不会按照顺序等待这一项工作结束才进行下一项工作,而是只要能抽身便去坐下一项工作,等前一项工作需要他的时候他再回来执行;同步编程就是一个比较死板的过程,必须严格按照顺序,这一项工作完全执行了才会执行下一项工作,这样浏览器会有很多白白等待的时间,非常浪费。
异步编程解决方法
①callback(回调函数),例如AJAX,但是存在许多问题,当嵌套层次深的时候就GG了会出现回调地狱,难以维护;由于每次都是新建立一个栈无法获取以前栈的信息,所以无法正确使用return,throw,没法正常检索以前的堆栈信息;多个回调之间难以建立联系,不知互相状态
②generator+co库
③async+await
④Promise函数
Promise函数图解思想
promise:主要用于异步计算;可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果;可以在对象之间传递和操作Promise,帮助我们处理队列
看了一个官方文档的翻译版本
https://www.ituring.com.cn/article/66566
根据每一个特点与方法翻译出代码,手写了Promise函数如下
class Promise {
constructor(excutor) {
//不能相信用户的输入
//参数校验
if (typeof excutor!=="function"){
throw new TypeError(`Promise resolver ${excutor} is not a function`)
//此处使用的是模板字符串
}
this.initValue()
this.initBind()
try{
excutor(this.resolve,this.reject)
} catch (e) {
this.reject(e)
}
//绑定this
initBind(){
this.resolve=this.resolve.bind(this)
this.reject=this.reject.bind(this)
}
initValue() {
this.value=null //终值
this.reason=null //拒因
this.state=Promise.PENDING //状态
this.onFulfilledCallbacks = [] //成功回调
this.onRejectedCallbacks = [] //失败回调
}
resolve(reason){
if(this.state==Promise.PENDING){
this.state=Promise.FULFILLED
this.value=value
this.onFulfilledCallbacks.forEach((fn)=>fn(this.value))
}
}
reject(reason){
if(this.state==PENDING){
this.state=Promise.REJECTED
this.reason=reason
this.onRejectedCallbacks.forEach((fn)=>fn(this.reason))
}
}
}
then(onFulfilled,onRejected){
//参数校验
if (typeof onFulfilled!=="function"){
onFulfilled=function (value) {
return value
}
}
if(typeof onRejected!=="function"){
onFulfilled=function (reason) {
throw reason
}
}
//实现链式调用,且改变了后面then的值,必须通过新的实例
let promise2=new Promise((resolve,reject)=> {
if (this.state === Promise.FULFILLED) {
const x= setTimeout(() => {
try{
const x= onFulfilled(this.value)
resolve(x)
}catch (e) {
reject(e)
}
})
}
if (this.state === Promise.REJECTED) {
setTimeout(() => {
try{
const x= onRejected(this.reason)
resolve(x)
}catch (e) {
reject(e)
}
})
}
if (this.state === Promise.PENDING) {
this.onFulfilledCallbacks.push(value => {
setTimeout(() => {
try {
const x= onFulfilled(this.value)
resolve(x)
}catch (e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push(reason => {
setTimeout(() => {
try{
const x= onRejected(this.reason)
resolve(x)
}catch (e) {
reject(e)
}
})
})
}
})
return promise2
}
}
Promise.PENDING='pending'
Promise.FULFILLED='fulfilled'
Promise.REJECTED='rejected'
Promise.resolvePromise=function (promise2,x,resolve,reject) {
//x与promise相等
if (promise2===x){
reject(new TypeError('Chaining cycle detected for promise'))
}
let called=false
//判断是否为Promise
if (x instanceof Promise){
x.then(value => {
Promise.resolvePromise(promise2,value,resolve.reject)
},
reason => {
reject(reason)
})
}else if (x!==null&&(typeof x==='object' || typeof x==='function')){
//x为对象或方法
try{
const then=x.then
if (typeof x.then === 'function'){
then.call(x,(value)=>{
if (called) return
called=true
Promise.resolvePromise(promise2,value,resolve.reject)
},reason => {
if (called) return
called=true
reject(reason)
})
}else {
if (called) return
called=true
resolve(x)
}
}catch (e) {
if (called) return
called=true
reject(e)
}
}else {
resolve(x)
}
}
以上!!!