Created
December 3, 2019 07:48
-
-
Save xxMrPHDxx/bfa819c4584fe3e44e2098d6d3a6ec5e to your computer and use it in GitHub Desktop.
Custom Promise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HttpResponse{ | |
constructor(status, statusText, body, headers={}){ | |
this.status = status; | |
this.statusText = statusText; | |
this.body = body; | |
this.headers = headers; | |
} | |
} | |
function fetch(url, options={}){ | |
const method = 'method' in options ? options['method'] : 'GET'; | |
const headers = 'headers' in options ? options['headers'] : {}; | |
const body = 'body' in options ? options['body'] : ''; | |
return new Promise((resolve, reject)=>{ | |
const req = new XMLHttpRequest(); | |
req.open(method, url); | |
req.send(body); | |
req.onreadystatechange = ()=>{ | |
if(req.readyState === 4){ | |
if(req.status === 200){ | |
const headers = {}; | |
for(let header of req.getAllResponseHeaders().split(/\n/g)){ | |
const [key, value] = header.split(': '); | |
headers[key] = value; | |
} | |
resolve(new HttpResponse(200, req.statusText, req.responseText, headers)); | |
}else{ | |
reject(`HttpError ${req.status}: ${req.statusText}`); | |
} | |
} | |
} | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Promise { | |
constructor(action){ | |
this.status = 'pending'; | |
this.value = this.error = undefined; | |
action((value=>{ | |
this.status = 'resolved'; | |
this.value = value; | |
}).bind(this),(error=>{ | |
this.status = 'rejected'; | |
this.error = error; | |
}).bind(this)); | |
} | |
then(callback){ | |
return new Promise((resolve, reject)=>{ | |
const timer = setInterval((()=>{ | |
if(this.status !== 'pending'){ | |
try{ | |
if(this.status === 'resolved') resolve(callback(this.value)); | |
else if(this.status === 'rejected') reject(this.error); | |
}catch(e){ | |
reject(e); | |
}finally{ | |
clearInterval(timer); | |
} | |
} | |
}).bind(this), 33) | |
}); | |
} | |
catch(callback){ | |
return new Promise((resolve, reject)=>{ | |
const timer = setInterval((()=>{ | |
if(this.status !== 'pending'){ | |
if(this.status === 'resolved'){ | |
resolve(this.value) | |
}else if(this.status === 'rejected'){ | |
reject(this.error); | |
callback(this.error); | |
} | |
clearInterval(timer); | |
} | |
}).bind(this)); | |
}); | |
} | |
finally(callback){ | |
return new Promise((resolve, reject)=>{ | |
const timer = setInterval((()=>{ | |
if(this.status !== 'pending'){ | |
(this.status === 'resolved' ? resolve : reject)(this.status === 'resolved' ? this.value : this.error); | |
callback(this.status === 'resolved' ? this.value : this.error); | |
clearInterval(timer); | |
} | |
}).bind(this), 33); | |
}); | |
} | |
static resolve(value){ | |
if(value instanceof Promise){ | |
return new Promise((resolve, reject)=>{ | |
const timer = setInterval((()=>{ | |
if(value.status !== 'pending'){ | |
if(value.status === 'resolved') resolve(value.value); | |
else if(value.status === 'rejected') reject(value.error); | |
clearInterval(timer); | |
} | |
}).bind(this)) | |
}) | |
} | |
return new Promise((resolve, reject)=>resolve(value)); | |
} | |
static all(array){ | |
return new Promise((resolve, reject)=>{ | |
const results = []; | |
for(const item of array){ | |
results.push(Promise.resolve(item)); | |
} | |
const timer = setInterval((()=>{ | |
for(const promise of results){ | |
if(promise.status === 'pending') return; | |
if(promise.status === 'rejected') reject(promise.error); | |
} | |
resolve(results.map(result=>result.value)); | |
}).bind(this), 33); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function log_return(value){ console.log(value); return value; } | |
Promise.resolve(new Promise((resolve, reject)=>{ | |
setTimeout(()=>{resolve(100)}, 1000); | |
})) | |
.then(log_return) | |
.then(val => val*2) | |
.catch(error => console.log('Nothing wrong here!')) | |
.finally(val => {console.log('Do nothing', val); return val;}) | |
.then(log_return) | |
.then(val => { | |
throw 'Invalid transaction!'; | |
}) | |
.catch(error => {alert(error); return error;}) | |
.finally(val => {console.log('Clearing transaction:', val);}) | |
Promise.all([1, 2, 3, 4]) | |
.then(console.log) | |
Promise.all([ | |
new Promise((resolve, reject)=>setTimeout(()=>resolve('Item A'), 1000)), | |
new Promise((resolve, reject)=>setTimeout(()=>resolve('Item B'), 2000)), | |
new Promise((resolve, reject)=>setTimeout(()=>resolve('Item C'), 3000)) | |
]) | |
.then(console.log) | |
fetch('Promise.js') | |
.then(res=>res.json()) | |
.catch(()=>{}) | |
.then(console.log) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment