思路
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)
})