当前位置:网站首页>Handwritten promise.resolve, promise reject, Promise.all
Handwritten promise.resolve, promise reject, Promise.all
2022-07-23 11:19:00 【Vivqst】
// // // promise/A+ The specification States promise There are three states , And once the state is changed, it cannot change again
const PENDING = 'Pending'
const FULFILLED = 'Fulfilled'
const REJECTED = 'Rejected'
class Promise {
// Higher order function , The argument to a function is a function , Higher order functions can realize the preset of parameters
// The function in the parameter of the function is the declaration of the function
// executor Is a function that executes immediately , Parameters are preset in constructor in
constructor(executor) {
this.state = PENDING
this.value = undefined // Successful results
this.reason = undefined // The reason for failure
// solve then Problems that can be called multiple times
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if(this.state === PENDING) {
this.state = FULFILLED
this.value = value
// When the state changes, execute the callback function
this.onResolvedCallbacks.forEach(cb => cb(value))
}
}
const reject = (reason) => {
if(this.state === PENDING) {
this.state = REJECTED
this.reason = reason
// When the state changes, execute the callback function
this.onRejectedCallbacks.forEach(cb => cb(reason))
}
}
// Here is executor Function call . Parameters of the incoming resolve and reject Two functions
try {
executor(resolve, reject)
} catch(err) {
reject(err)
}
}
then(onFulfilledCallback, onRejectedCallback) {
onFulfilledCallback = typeof onFulfilledCallback === 'function' ? onFulfilledCallback : value => value
onRejectedCallback = typeof onRejectedCallback === 'function' ? onRejectedCallback : reason => {
throw reason }
// You can chain call , be then It must be a Promise
let promise = new Promise((resolve, reject) => {
if(this.state === FULFILLED) {
// Optimize to catch exceptions
setTimeout(() => {
try {
let res = onFulfilledCallback(this.value)
// according to res Different types of
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
}
if(this.state === REJECTED) {
setTimeout(() => {
try {
let res = onRejectedCallback(this.reason)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
}
// When executor When an asynchronous task occurs ,then When it comes to execution , The state has not changed , You can put the callback into the callback function array
if(this.state === PENDING) {
this.onResolvedCallbacks.push((value) => {
setTimeout(() => {
try {
let res = onFulfilledCallback(value)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
let res = onRejectedCallback(reason)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
})
}
})
return promise
}
static resolve(value) {
if(value instanceof Promise) {
return value
} else {
return new Promise((resolve, reject) => {
resolve(value)
})
}
}
static reject(reason) {
if(reason instanceof Promise) {
return reason
} else {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
catch(onRejectedCallback) {
this.then(null, onRejectedCallback)
}
static all(args) {
let results = []
let i = 0 // Number of correct results
let iteratorIndex = -1 // Traverse index , The initial value is -1, Traverse from 0 Start
return new Promise((resolve, reject) => {
for (const item of args) {
iteratorIndex += 1
Promise.resolve(item).then(res => {
results[iteratorIndex] = res
i++
if(i === (iteratorIndex + 1)) {
resolve(results)
}
}).catch(err => {
reject(err)
})
}
})
}
}
function resolvePromise(promise, res, resolve, reject) {
if(res === promise) {
return reject(new TypeError(' Dead cycle '))
}
if(res instanceof Promise) {
try {
res.then(x => {
resolvePromise(promise, x, resolve, reject)
// resolve(x)
})
} catch(e) {
reject(e)
}
} else {
resolve(res)
}
}
边栏推荐
猜你喜欢
随机推荐
Large factory interview machine learning algorithm (0): Feature Engineering | data preprocessing
Error when PLSQL creates Oracle Database: when using database control to configure the database, it is required to configure the listener in the current Oracle home directory. You must run netca to co
Sorting out common SQL interview questions and answers
BurpSuite学习笔记
Shardingsphere sub database and table scheme
js的继承方式
分页、过滤
高阶函数的应用:手写Promise源码(四)
[Doris]配置和基本使用contens系统(有时间继续补充内容)
my_strcpy的实现(经典,简单,实用,收藏)
JDBC Learning and simple Encapsulation
C语言之二分查找法或折半查找法剖析(经典例题,经典解析)
First meet flask
Copy a project /project in idea
[Python flask note 5] Blueprint simple à utiliser
从零开始的pytorch小白使用指北
Getting started with RPC and thrift
第一篇博客
pyspark学习笔记
[python flask notes 5] blueprint is easy to use








