手写promise
tips
- Ajax是一种服务端与浏览器之间的异步通信方式
- XML是一种数据传输格式,现在大多用json
实现Ajax
//创建一个XMLHttpRequest()对象
const xhr = new XMLHttpRequest();
对于一个xhr对象,他有一个属性是readyState
可能的值 | 描述 |
---|---|
0 |
未初始化 |
1 |
连接已建立 |
2 |
请求已接收 |
3 |
请求处理中 |
4 |
请求已完成 |
readyState
属性变化时,会触发readystatechange
事件然后会调用onreadystatechange
,所以我们可以在这个onreadystatechange
上定义一些回调
onreadystatechange = (event) => {};
//也可以用这种方法
addEventListener("readystatechange", (event) => {});
//
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', 'text.json', true);//init
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload=function(){
//请求结束后的处理代码
}
xhr.send(null);//要发送的数据体
promise好难啊我焯😧
class MyPromise{
constructor(executor){
this.status="pending",
this.value=undefined,
this.reason=undefined,
this.onFulFilledCallbacks=[],
this.onRejectedCallbacks=[]
const resolve=(value)=>{
if(this.status==="pending"){
this.status="fulfilled"
this.value=value
this.onFulFilledCallbacks.forEach(callback => {
callback(value)
});
}
}
const reject=(reason)=>{
if(this.status==="pending"){
this.status="rejected"
this.reason=reason
this.onRejectedCallbacks.forEach(callback=>{
callback(reason)
})
}
}
try {
executor(resolve,reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:value=>value
onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason}
return new MyPromise((resolve,reject)=>{
if(this.status==="fulfilled"){
setTimeout(()=>{
const result=onFulfilled(this.value)
resolve(result)
})
}else if(this.status==="rejected"){
setTimeout(()=>{
const result=onRejected(this.reason)
reject(result)
})
}else{
this.onFulFilledCallbacks.push(()=>{
setTimeout(()=>{
const result=onFulfilled(this.value)
resolve(result)
})
})
this.onRejectedCallbacks.push(()=>{
setTimeout(()=>{
const result=onRejected(this.reason)
reject(result)
})
})
}
})
}
catch(onRejected){
return this.then(null,onRejected)
}
finally(onFinally){
return this.then(onFinally,onFinally)
}
static resolve(value){
if(value instanceof MyPromise){
return value
}
return new MyPromise(resolve=>resolve(value))
}
static all(promiseArr){
return new MyPromise((resolve,reject)=>{
if(!Array.isArray(promiseArr)){
return reject(new Error("传入的参数不是数组!"))
}
const res=[]
let count=0
for(let i=0;i<promiseArr.length;i++){
// const isPromise=Object.prototype.toString.call(promiseArr[i]==='[Object Promise]')
MyPromise.resolve(promiseArr[i]).then(value=>{
res[i]=value
count++
if(count===promiseArr.length){
resolve(res)
}
}).catch(e=>reject(e))
}
})
}
static race(promiseArr){
return new Promise((resolve,reject)=>{
if(!Array.isArray(promiseArr)){
return reject(new Error("传入的参数不是数组!"))
}
for(let i=0;i<promiseArr.length;i++){
MyPromise.resolve(promiseArr[i]).then(value=>{
resolve(value)
}).catch(e=>{reject(e)})
}
})
}
}