試圖寫了一下,大概測試了一下,沒有用專業的測試工具測試....git
代碼感受仍是寫的比較好懂的,本人水平較差,若是測試有問題,歡迎回復指出
地址: https://github.com/julyL/Code...github
(function(global) { function isFunction(val) { return typeof val == 'function'; } function isObject(val) { return typeof val == 'object'; } function asyncExcute(fn) { return function() { setTimeout(fn); // 同一執行隊列中,原生Promise是先於setTimeout實現的,本身實現暫時用setTimeout模擬 } } function Promise(fn) { if (!isFunction(fn) || this instanceof Promise == false) { throw new TypeError("Promise必須傳入function而且new構造") } this.status = 'pending'; this.value = undefined; // promise狀態改變以後傳遞的值 this.thenPromise = undefined; //執行then以後返回的promise this.resolveQueue = []; // this.rejectQueue = []; // var re = asyncExcute(function(resolveData) { this._resolve(resolveData) }.bind(this)), //這裏必須異步處理,不然then函數執行之前可能就已經執行了_resolve,但這時then中函數還未加入resolveQueue中 rj = asyncExcute(function(resolveData) { this._reject(resolveData) }.bind(this)); try { fn(re, rj) } catch (error) { this.status = 'reject'; this.value = error; asyncExcute(function(){this._reject(error)}); // new Promise(()=>{ 出現異常... }).then(refn,rjfn); 出現異常時then還未執行, rjfn還未加入到rejectQueue中 } } Promise.prototype.then = function(refn, rjfn) { var returnPro = new Promise(function() {}); this.thenPromise = returnPro; this.resolveQueue.push(refn); this.rejectQueue.push(rjfn); if (this.status == 'resolve') { //執行then時,若是狀態已經不是pending,則執行相應函數 this._resolve(this.value); } if (this.status == 'reject') { this._reject(this.value); } return returnPro; } Promise.prototype._resolve = function(resolveData) { var handle, returnVal; this.status = "resolve"; this.value = resolveData; while (this.resolveQueue.length > 0) { //2.2.6 當 promise 成功執行時,全部 onFulfilled 需按照其註冊順序依次回調 handle = this.resolveQueue.shift(); if (!isFunction(handle)) { //不是函數 2.1.1 onFulfilled 不是函數,其必須被忽略 this.thenPromise.value = resolveData; this.thenPromise.status = 'resolve'; this.thenPromise._resolve(); return; } try { //若是 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執行,並返回拒因 e returnVal = handle(resolveData); } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } if (isObject(returnVal || isFunction(returnVal))) { //若是返回值爲對象或者函數 if (returnVal == this.thenPromise) { //若是 promise 和 x 指向同一對象,以 TypeError 爲據因拒絕執行 promise this.thenPromise.status = 'reject'; this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一對象'); } else if (returnVal instanceof Promise) { //若是 x 爲 Promise ,則使 promise 接受 x 的狀態 try { then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise)); } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } } else { //若是 x 爲對象或者函數 try { //若是取 x.then 的值時拋出錯誤 e ,則以 e 爲據因拒絕 promise var then = returnVal.then; if (isFunction(then)) { then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise)); } } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } } } else { this.thenPromise.value = returnVal; this.thenPromise.status = 'resolve'; this.thenPromise._resolve(); } } } Promise.prototype._reject = function(resolveData) { var handle, returnVal; this.status = "resolve"; this.value = resolveData; while (this.rejectQueue.length > 0) { //2.2.6 當 promise 成功執行時,全部 onFulfilled 需按照其註冊順序依次回調 handle = this.rejectQueue.shift(); if (!isFunction(handle)) { //不是函數 2.1.1 onFulfilled 不是函數,其必須被忽略 this.thenPromise.value = resolveData; this.thenPromise.status = 'resolve'; this.thenPromise._resolve(); return; } try { //若是 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執行,並返回拒因 e returnVal = handle(resolveData); } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } if (isObject(returnVal || isFunction(returnVal))) { //若是返回值爲對象或者函數 if (returnVal == this.thenPromise) { //若是 promise 和 x 指向同一對象,以 TypeError 爲據因拒絕執行 promise this.thenPromise.status = 'reject'; this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一對象'); } else if (returnVal instanceof Promise) { //若是 x 爲 Promise ,則使 promise 接受 x 的狀態 try { then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise)); } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } } else { //若是 x 爲對象或者函數 try { //若是取 x.then 的值時拋出錯誤 e ,則以 e 爲據因拒絕 promise var then = returnVal.then; if (isFunction(then)) { then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise)); } } catch (error) { this.thenPromise.status = 'reject'; this.thenPromise.value = error; this.thenPromise._reject(); } } } else { this.thenPromise.value = returnVal; this.thenPromise.status = 'resolve'; this.thenPromise._resolve(); } } } Promise.resolve = function(value) { return new Promise(function(re, rj) { re(value) }) } Promise.reject = function(value) { return new Promise(function(re, rj) { re(value) }) } Promise.all = function(queue) { if (Object.prototype.toString.call(queue) != "[object Array]") { return; } var returnPromise = new Promise(function() {}), resolveNum = 0; for (var i = 0; i < queue.length; i++) { queue[i].then(function() { resolveNum++; if (resolveNum == queue.length) { returnPromise._resolve(); } }); } return returnPromise; } Promise.race = function(queue) { if (Object.prototype.toString.call(queue) != "[object Array]") { return; } var returnPromise = new Promise(function() {}), resolveNum = 0; for (var i = 0; i < queue.length; i++) { queue[i].then(function() { returnPromise._resolve(); }); } return returnPromise; } global.Promise = Promise; })(window);