// promise 狀態 const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; const isFn = fn => typeof fn === 'function'; class Promise { constructor(resolver) { if (!isFn(resolver)) { throw new TypeError('Promise 參數必須是函數'); } //狀態和值 this._status = PENDING; this._value; //執行隊列 this._fulfilledQueue = []; this._rejectedQueue = []; //綁定this this._resolve = this._resolve.bind(this); this._reject = this._reject.bind(this); resolver(this._resolve, this._reject); } _resolve(val) { if (this._status !== PENDING) return; //由於Promise裏面的函數是同步的,then是異步的 setTimeout(() => { this._status = FULFILLED; this._value = val; let cb; while (cb = this._fulfilledQueue.shift()) { cb(this._value) } }, 0); } _reject(val) { if (this._status !== PENDING) return; //由於Promise裏面的函數是同步的,then是異步的 setTimeout(() => { this._status = REJECTED; this._value = val; let cb; while (cb = this._rejectedQueue.shift()) { cb(this._value) } }, 0); } // then 參數類型: //(1)值 //(2)函數, 返回值或者Promise then(onFulfilled, onRejected) { return new Promise((resolve, reject) => { // 返回一個 resolve 或者 reject 函數 let runThen = (callback, resolver) => { return function (val) { try { if (!isFn(callback)) { // 判斷 onFulfilled、onRejected 是不是一個 function,否的話直接透傳value resolver(val) } else { const res = callback(val); // 判斷函數返回值是不是一個 Promise if (res instanceof Promise) { res.then(resolve, reject); } else { resolver(res) } } } catch (err) { reject(err); } } } //判斷當前的status switch (this._status) { case FULFILLED: runThen(onFulfilled, resolve)(this._value); break; case REJECTED: runThen(onRejected, reject)(this._value); break; case PENDING: //狀態未變,將函數添加到執行隊列,等待狀態改變後執行 this._fulfilledQueue.push(runThen(onFulfilled, resolve)); this._rejectedQueue.push(runThen(onRejected, reject)); break; } }); } static resolve(promise) { // 判斷 promise 是不是一個 promise 對象 if (promise instanceof Promise) { return promise; } else { return new Promise(resolve => { resolve(promise); }); } } static reject(err){ return new Promise((resolve, reject) => reject(err)); } catch(onRejected) { return this.then(undefined, onRejected); } finally(callback) { return this.then( value => Promise.resolve(callback()).then(() => value), reason => Promise.resolve(callback()).then(() => { throw reason }) ); } static race(pmList) { return new Promise((resolve, reject) => { pmList.forEach(item => { // item 可能不是 promise,因此先調用 promise.resolve Promise.resolve(item).then(val => { resolve(val); }, err => { reject(err); }); }) }) } static all(pmList) { return new Promise((resolve, reject) => { let resolveArr = []; let count = 0; pmList.forEach((item, index) => { // item 可能不是 promise,因此先調用 promise.resolve Promise.resolve(item).then(val => { resolveArr[index] = val; count++; if (count === pmList.length) { resolve(resolveArr); } }, err => { reject(err); }); }) }) } } 複製代碼