手撕promise(持续更新)

思路

promise三个状态:
pending:等待态,此时函数未被调用
fulfilled:成功态,函数调用resolve方法
rejected:失败态,函数调用reject方法
此外,由于then方法遇到的异步等待和回调第二个 promise2 ,还要考虑维护两个栈(分别是 resolvedCallbacks 和 rejectedCallbacks )和 resolvePromise 判断调用值。

手撕代码

Class Promise {
	constructor(executor){
		this.state = "pending"
		this.value = null
		this.reason = null
		this.ResolvedCallbacks = []
		this.RejectedCallbacks = []
		let resolve = value =>{
			if(this.state === "pending"){
				this.state = "fulfilled"
				this.value = value
				this.ResolvedCallbacks.forEach(fn => fn())
			}
	    }
	    let reject = reason =>{
			if(this.state === "pending"){
				this.state = "rejected"
				this.reason = reason
				this.RejectedCallbacks.forEach(fn => fn())
			}
	    }
	    try{
			executor(resolve,reject)
		}catch(err){
			reject(err)
		}
    }
    then(onFulfilled,onRejected){
    	let promise2 = new Promise(resolve,reject){
    		if(this.state === "fulfilled"){
    			let x = onFulfilled(this.value)
    			resolvePromise(promise2,x,resolve,reject)
    		}
    		if(this.state === "rejected"){
    			let x = onRejected(this.reason)
    			resolvePromise(promise2,x,resolve,reject)
    		}
    		if(this.state === "pending"){
    			//存进对应的栈里等待
    			this.ResolvedCallbacks.push(()=>{
    				let x = onFulfilled(this.value)
    				resolvePromise(promise2,x,resolve,reject)
    			})
    			this.RejectedCallbacks.push(()=>{
    				let x = onRejected(this.value)
    				resolvePromise(promise2,x,resolve,reject)
    			})
    		}
    	}
    	return promise2
    }
}
//定义resolvePromise方法
function resolvePromise(promise2,x,resolve,reject){
	if(x === promise2){
		return reject(new TypeError("Chaining cycle detected for promise"))
	}
	let called;
	if(x!=null && (typeof x === "object" || typeof x === "function")){
		try{
			let then = x.then
			if(typeof then === "function"){
				then.call(x,y =>{
					if(this.called) return
					this.called = true
					resolvePromise(promise2,y,resolve,reject)
				},err => {
					if(this.called) return
					this.called = true
					reject(err)
				})
			}else{
				resolve(x)
			}
		}catch(err){
			if(this.called) return
			this.called = true
			reject(err)
		}
	}else{
		resolve(x)
	}
}

Promise封装ajax

1.get方式

let url = ""
vae getRequest = url =>{
	let p = new Promise((resolve,reject) => {
		let xhr = new XMLHttpRequest()
		xhr.open('GET',url,true)
		xhr.onreadystatechange = () =>{
			if(this.readystate === 4){
				if(this.status === 200){
					resolve(this.responseText)
				}
			}else{
				reject("failed")
			}
		}
		xhr.send()
	})
	return p
}
//应用
getRequest(url).then(data => {
	console.log("success:"+data)
}.catch(err => {
	console.log("fail:"+err)
})

2.post方式

let url = ""
function postRequest(url,data){
	let p = new Promise((resolve,reject)=>{
		let xhr = new XMLHttpRequest()
		xhr.open('POST',url,true)
		xhr.onreadystatechange = () => {
			if(this.readystate === 4){
				if(this.status === 200){
					resolve(this.responseText)
				}
			}else{
				reject("failed")
			}
		}
		xhr.send(JSON.stringify(data))
	})
	return p
}
//运用
postRequest(url).then(data => {
	console.log("success:"+data)
}).catch(err => {
	console.log("fail:"+err)
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值