class Promise { constructor(handle) { if (typeof handle !== "function") { throw new Error("promise must accept a function as a parameter"); } // 定义三种状态配置 this.STATUS = { PENDING: "pending", FULFILLED: "fulfilled", REJECTED: "rejected" }; // 初始化状态 this._status = this.STATUS.PENDING; // 初始化值 this._value = undefined; // 胜利状态须要执行的工作队列 this._fulfilledQueues = []; // 失败状态须要执行的工作队列 this._rejectedQueues = []; // 执行handle try { handle(this._resolve.bind(this), this._reject.bind(this)); } catch (err) { this._reject(err); } } // Object.prototype.toString.call(promiseObj) === "[object Promise]" get [Symbol.toStringTag](){ return "Promise" } _runMicroTask(callback) { // 应用浏览器MutationObserver WEB.API实现then办法的微工作机制 let count = 0; const observer = new MutationObserver(callback); // 创立文本节点,节约资源 const textNode = document.createTextNode(String(count)); observer.observe(textNode, { // 当文本扭转时触发回调 characterData: true }); // 扭转文本,回调callback触发 textNode.data = String(++count); } _resolve(val) { if (this._status !== this.STATUS.PENDING) return; const onFulfilled = v => { this._status = this.STATUS.FULFILLED; this._value = v; let cb; while ((cb = this._fulfilledQueues.shift())) { cb(v); } }; const onRejected = err => { this._status = this.STATUS.REJECTED; this._value = err; let cb; while ((cb = this._rejectedQueues.shift())) { cb(err); } }; // 顺次执行胜利队列中的函数,并清空队列 const run = () => { if (val instanceof Promise) { // 如果入参是一个Promise,则val的status及value值决定了以后promise实例的status和value值 val.then(onFulfilled, onRejected); } else { onFulfilled(val); } }; this._runMicroTask(run); } _reject(val) { if (this._status !== this.STATUS.PENDING) return; // 顺次执行失败队列中的函数,并清空队列 const run = () => { this._status = this.STATUS.REJECTED; this._value = val; let cb; while ((cb = this._rejectedQueues.shift())) { cb(val); } }; this._runMicroTask(run); } then(onFulfilled, onRejected) { // then反对链式调用,返回一个新的promise return new Promise((resolve, reject) => { const handleResolve = value => { try { if (typeof onFulfilled !== "function") { // 如果onFulfilled不是函数,则间接返回以后promise的value值 resolve(value); } else { const res = onFulfilled(value); // Promise.prototype 是否存在于res的原型链上,是则阐明res是Promise实例 if (res instanceof Promise) { res.then(resolve, reject); } else { resolve(res); } } } catch (err) { reject(err); } }; const handleReject = value => { try { if (typeof onRejected !== "function") { // 如果onFulfilled不是函数,则间接返回以后promise的value值 resolve(value); } else { const res = onRejected(value); if (res instanceof Promise) { res.then(resolve, reject); } else { resolve(res); } } } catch (err) { reject(err); } }; switch (this._status) { case this.STATUS.PENDING: this._fulfilledQueues.push(handleResolve); this._rejectedQueues.push(handleReject); break; case this.STATUS.FULFILLED: handleResolve(this._value); break; case this.STATUS.REJECTED: handleReject(this._value); break; } }); } catch(onRejected) { return this.then(null, onRejected); } // 增加动态resolve办法 static resolve(value) { // 如果参数是MyPromise实例,间接返回这个实例 if (value instanceof Promise) return value; return new Promise(resolve => resolve(value)); } // 增加动态reject办法 static reject(err) { return new Promise((resolve, reject) => reject(err)); } // 增加动态all办法,所有promise入参状态产生扭转后才扭转状态 static all(list) { return new Promise((resolve, reject) => { const length = list.length; let count = 0; let values = []; // // entries返回数组的键值对[[index, value]...] // for (let [i, p] of list.entries()) { // // } for (let i = 0; i < length; i++) { const promise = list[i]; promise.then( res => { // promise有可能异步执行resolve,不能用push values[i] = res; count++; if (count === length) { resolve(values); } }, err => { // 只有子元素promise中有任何一个reject,则返回的promise rejected reject(err); } ); } }); } // 增加动态race办法 static race(list) { return new Promise((resolve, reject) => { for (let p of list) { // 只有有一个实例率先扭转状态,新的MyPromise的状态就跟着扭转 this.resolve(p).then( res => { resolve(res); }, err => { reject(err); } ); } }); } /*finally() 办法返回一个Promise。 在promise完结时,无论后果是fulfilled或者是rejected,都会执行指定的回调函数。 这为在Promise是否胜利实现后都须要执行的代码提供了一种形式。 这防止了同样的语句须要在then()和catch()中各写一次的状况。*/ finally(handle) { return this.then( value => { handle(); return Promise.resolve(value); }, err => { handle(); return Promise.reject(err); } ); }}// console.log(Promise.resolve)// // new Promise((res, rej) => setTimeout(() => rej(777)), 1000)// // .then(res => console.log({res}), err => console.log(1, err))// // .then(res => console.log({res}), err => console.log(2, err))//// console.log(Promise.resolve(Promise.resolve(222)))////// // new Promise((res, rej) => rej(666))// // .then(res => console.log({res}), err => new Promise(res => setTimeout(() => res (123),3000)))// // .then(res => console.log({then2: res}), err => console.log(2, err))//// new Promise((res, rej) => res(new Promise((r, err) => err(857))))// .then(null, e => new Promise(res => res(111)))// .then(a => console.log({a})).catch(cat => console.log({cat}))console.log("哇哈哈");setTimeout(() => { console.log("setTimeout");}, 0);new Promise((res, rej) => { rej(111);}) .finally(() => { console.log("执行finally"); }) .then(null, err => console.log({ err }));console.log("666");if (window) { console.log("you dinwow");}