Class ZPromise {// Define three states static PENDING ='PENDING';
static RESOLVED = 'RESOLVED';
static REJECTED = 'REJECTED'; Constructor (handler) {// Type check, argument is not a function throw errorif( typeof handler ! = ='function' ) throw new TypeError('Promise resolver undefined is not a function'); This. ResolvedQueues = []; this.rejectedQueues = []; this.finayllyQueues = []; // Class status this.status = zpromise.pending; // The value of the class used to pass the return value this.value; Handler (this._resolve.bind(this), this._reject. Bind (this)); } _resolve(val) { //setTimeout(_=>{ // }, 0); // Use message to emulate the resolve microtask window.addeventListener ('message', _=>{// Once the state changes, it can't changeif(this.status ! == ZPromise.PENDING)return;
// console.log('_resolve'); This. Status = zpromise.resolved; this.value = val;let handler;
while(handler = this. ResolvedQueues. Shift ()) {/ / state into a resolved after callthenHandler (this.value); } // Call _finally this._finally(this.value); }); window.postMessage(' ');
}
_reject(val) {
// setTimeout(_=>{
// }, 0);
window.addEventListener('message', _ = > {if(this.status ! == ZPromise.PENDING)return;
this.status = ZPromise.REJECTED;
this.value = val;
let handler;
while( handler = this.rejectedQueues.shift() ) {
handler(this.value);
}
this._finally(this.value);
});
window.postMessage(' '); } // State changes will call the end function_finally() {
window.addEventListener('message', _=>{
this.status = ZPromise.REJECTED;
let handler;
while( handler = this.finayllyQueues.shift() ) { handler(this.value); }}); window.postMessage(' ');
}
then( resolvedHandler, rejectedHandler ) { // resolvedHandler(); // this. ResolvedQueues. Push (resolvedHandler); // this.rejectedQueues.push(rejectedHandler); // For chain calls.thenA new promise is returned and the value val is acceptedreturn new ZPromise( (resolve, reject) => {
// resolve();
functionNewResolvedHandler (val) {/ / rightthenFunction argument type, whether it's a function, whether it's a promiseif (typeof resolvedHandler === 'function') {
let result = resolvedHandler(val);
if (result instanceof ZPromise) {
result.then(resolve, reject);
} else{ resolve(result); }}else{ resolve(val); }}function newRejectedHandler(val) {
if (typeof rejectedHandler === 'function') {
let result = rejectedHandler(val);
if (result instanceof ZPromise) {
result.then(resolve, reject);
} else{ reject(result); }}else{ reject(val); }} this.resolvedqueues. Push (newResolvedHandler); this.rejectedQueues.push(newRejectedHandler); }); } catch(rejectedHandler) {return this.then(undefined, rejectedHandler);
}
finally(finallyHandler) {
this.finayllyQueues.push(finallyHandler);
}
// 定义静态方法
static resolve(val) {
return new ZPromise(resolve => {
resolve(val);
});
}
static reject(val) {
return new ZPromise((resolve, reject) => {
reject(val);
});
}
static all(iterator) {
let len = iterator.length;
let i = 0;
let vals = [];
return new ZPromise( (resolve, reject) => {
iterator.forEach(it => {
it.then(val => {
i++;
vals.push(val);
if(I === len) {resolve(vals); }}). Catch (e=> {reject(e); }); }); }); } static race(iterator) {return new ZPromise((resolve, reject) => {
iterator.forEach(it => {
it.then(val => {
resolve(val);
}).catch(e=> {
reject(e);
});
});
})
}
static allSettled(iterator) {
let len = iterator.length;
let i = 0;
let vals = [];
return new ZPromise( (resolve, reject) => {
iterator.forEach(it => {
it.finally(val => {
i++;
vals.push(val);
if(i === len) { resolve(vals); } }).catch(e=>{}) }); }); }} ()Copy the code