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