当前位置:网站首页>JS promise implementation logic
JS promise implementation logic
2022-07-28 05:56:00 【Quiet sky】
One 、promise Realization
Realize the core points
- Promise It's a micro task
- call chaining
class MyPromise {
static PENDING = 'PENDING'
static FULFILED = 'FULFILED'
static REJECTED = 'REJECTED'
constructor(callback) {
if (typeof callback !== 'function') {
throw new TypeError('promise resolve undefined is no a function')
}
this.status = MyPromise.PENDING
this.value = null
this.resolveQueues = []
this.rejuectQueues = []
callback(this._resolve.bind(this), this._reject.bind(this))
}
_resolve(val) {
// adopt window.postMessage Implement micro tasks
window.addEventListener('message', () => {
if (this.status !== MyPromise.PENDING) return
this.value = val
this.status = MyPromise.FULFILED
let handleFun = this.resolveQueues.shift()
if (handleFun) {
handleFun(this.value)
}
})
window.postMessage('')
}
_reject(val) {
window.addEventListener('message', () => {
if (this.status !== MyPromise.PENDING) return
this.value = val
this.status = MyPromise.REJECTED
let handleFun = this.rejuectQueues.shift()
if (handleFun) {
handleFun(this.value)
}
})
window.postMessage('')
}
then(resolveFun, rejectFun) {
// Call... Recursively again MyPromise To achieve chained calls
return new MyPromise((resolve, reject) => {
// take resolveFun and resolve Put in the queue at the same time , Make the call output in order
function resolveHandle(val) {
if (typeof resolveFun === 'function') {
let result = resolveFun(val)
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} else {
resolve(val)
}
}
function rejectHandle(val) {
if (typeof rejectFun === 'function') {
let result = rejectFun()
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
reject(result)
}
reject(err)
} else {
reject(val)
}
}
this.resolveQueues.push(resolveHandle)
this.rejuectQueues.push(rejectHandle)
})
}
catch(rejectFun) {
this.then(undefined, rejectFun)
}
}
new MyPromise((resolve, reject) => {
resolve(1)
}).then((val) => {
console.log('then1', val)// First, the output then1 1
return 2
}).then((val) => {
console.log('then2', val)// Then the output then2 2
})
Two 、promise.all Realization
static all(iterator){
let len = iterator.length;
let n = 0;
let result= [];
return new AlleyPromise((resolve,reject)=>{
iterator.forEach((item, index)=>{
item.then((val)=>{
++n;
result[index] = val
if(len === n) {
resolve(result);
}
}).catch((e)=>{
reject(e);
})
})
}
3、 ... and 、promise.race Realization
static race(iterator){
return new AlleyPromise((resolve,reject)=>{
iterator.forEach((item)=>{
item.then((val)=>{
resolve(val);
}).catch((e)=>{
reject(e);
})
})
})
}
Four 、promise.resolve Realization
static resolve(val){
return new AlleyPromise((resolve)=>{
resolve(val)
})
}
5、 ... and 、promise.reject Realization
static reject(val){
return new AlleyPromise((resolve,reject)=>{
reject(val)
})
}
6、 ... and 、 Complete method
class MyPromise {
static PENDING = 'PENDING'
static FULFILED = 'FULFILED'
static REJECTED = 'REJECTED'
constructor(callback) {
if (typeof callback !== 'function') {
throw new TypeError('promise resolve undefined is no a function')
}
this.status = MyPromise.PENDING
this.value = null
this.resolveQueues = []
this.rejuectQueues = []
callback(this._resolve.bind(this), this._reject.bind(this))
}
_resolve(val) {
// adopt window.postMessage Implement micro tasks
window.addEventListener('message', () => {
if (this.status !== MyPromise.PENDING) return
this.value = val
this.status = MyPromise.FULFILED
let handleFun = this.resolveQueues.shift()
if (handleFun) {
handleFun(this.value)
}
})
window.postMessage('')
}
_reject(val) {
window.addEventListener('message', () => {
if (this.status !== MyPromise.PENDING) return
this.value = val
this.status = MyPromise.REJECTED
let handleFun = this.rejuectQueues.shift()
if (handleFun) {
handleFun(this.value)
}
})
window.postMessage('')
}
then(resolveFun, rejectFun) {
// Call... Recursively again MyPromise To achieve chained calls
return new MyPromise((resolve, reject) => {
// take resolveFun and resolve Put in the queue at the same time , Make the call output in order
function resolveHandle(val) {
if (typeof resolveFun === 'function') {
let result = resolveFun(val)
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} else {
resolve(val)
}
}
function rejectHandle(val) {
if (typeof rejectFun === 'function') {
let result = rejectFun()
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
reject(result)
}
reject(err)
} else {
reject(val)
}
}
this.resolveQueues.push(resolveHandle)
this.rejuectQueues.push(rejectHandle)
})
}
catch(rejectFun) {
this.then(undefined, rejectFun)
}
static all(iterator){
let len = iterator.length;
let n = 0;
let result= [];
return new AlleyPromise((resolve,reject)=>{
iterator.forEach((item, index)=>{
item.then((val)=>{
++n;
result[index] = val
if(len === n) {
resolve(result);
}
}).catch((e)=>{
reject(e);
})
})
}
static race(iterator){
return new AlleyPromise((resolve,reject)=>{
iterator.forEach((item)=>{
item.then((val)=>{
resolve(val);
}).catch((e)=>{
reject(e);
})
})
})
}
static resolve(val){
return new AlleyPromise((resolve)=>{
resolve(val)
})
}
static reject(val){
return new AlleyPromise((resolve,reject)=>{
reject(val)
})
}
}
边栏推荐
猜你喜欢
随机推荐
扩展欧几里得定理
js-宏任务和微任务
ArcGIS Engine Development Resources
ArcGIS Engine开发资源
话题功能实现
js中==和===区别
curd组件中的时间设置
结果填空 星系炸弹(Excel秒杀)
(php毕业设计)基于php水果销售商店管理系统获取
DOM基础
基于php心理健康服务系统获取(php毕业设计)
Cookie、Session和Token的区别与联系
Mars数*字*藏*品*平*台守卫者计划细节公布
结果填空 第39级台阶(递归*C语言)
Zotero - a document management tool
Apache Log4j任意代码执行复现
ES6----解构赋值
NSCTF-web题目writeup
CTF常见加密方式JS
ArrayList multithreading security solution









