Promise实现
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
class Promise{
constructor(exector){
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(fn=>fn(this.value));
}
}
const reject = reason => {
if(this.status === PENDING){
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn=>fn(this.reason));
}
}
try{
exector(resolve,reject);
}
catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:value=>value;
onRejected = typeof onRejected === 'function'?onRejected:
reason => {throw new Error(reason instanceof Error?reason.message:reason)}
const self = this;
return new Promise((resolve,reject)=>{
if(self.status === PENDING){
self.onFulfilledCallbacks.push(()=>{
try{
setTimeout(()=>{
const result = onFulfilled(self.value);
result instanceof Promise?result.then(resolve,reject):resolve(result)
})
}
catch(e){
reject(e);
}
})
self.onRejectedCallbacks.push(()=>{
try{
setTimeout(()=>{
const result = onRejected(self.reason);
result instanceof Promise?result.then(resolve,reject):reject(result)
})
}
catch(e){
reject(e);
}
})
}
else if(self.status === FULFILLED){
setTimeout(()=>{
try{
const result = onFulfilled(self.value);
result instanceof Promise?result.then(resolve,reject):resolve(result)
}
catch(e){
reject(e)
}
})
}
else if(self.status === REJECTED){
setTimeout(()=>{
try{
const result = onRejected(self.reason);
result instanceof Promise?result.then(resolve,reject):reject(result)
}
catch(e){
reject(e)
}
})
}
})
}
catch(onRejected){
return this.then(null,onRejected)
}
static resolve(value){
if(value instanceof Promise){
return value
}
else{
return new Promise((resolve,reject) => resolve(value))
}
}
static reject(reason){
return new Promise((resolve,reject) => {
reject(reason)
})
}
}
static all(PromiseAll){
let length = PromiseAll.length;
let result = new Array(length);
let count =0;
return new Promise((resolve,reject)=>{
for(let i=0;i<length;i++){
Promise.resolve(PromiseAll[i]).then(val=>{
result[i] = val;
count++;
if(count === length){
resolve(result);
}
},
err => reject(err)
)
}
})
}
static race(PromiseArr){
return new Promise((resolve,reject)=>{
PromiseArr.forEach((p)=>{
Promise.resolve(p).then(
val => resolve(val),
err => reject(err)
)
})
})
}
Promise调度器
class Scheduler{
constructor(){
this.queue = [];
this.maxCount = 2;
this.runCount = 0;
}
add(promiseTask){
this.queue.push(promiseTask);
}
taskStart(){
for(let i= 0;i<this.maxCount;i++){
this.request();
}
}
request(){
if(!this.queue||this.queue.length||this.runCount>=this.maxCount){
return;
}
this.runCount++;
this.queue.shift()().then(()=>{
this.runCounts--;
this.request();
})
}
}
const scheduler = new Scheduler();
const sleep = time => new Promise(resolve => {
setTimeout(resolve,time)
})
const addTask = (time,order)=>{
scheduler.add(()=>sleep(time).then(()=>console.log(order)));
}
addTask(1000,'1')
addTask(500,'2')
addTask(300,'3')
addTask(400,'4')
scheduler.taskStart();
2 3 1 4