摘要:試圖寫了一下大概測試了一下沒有用專業的測試工具測試代碼感覺還是寫的比較好懂的,本人水平較差,如果測試有問題,歡迎回復指出地址同一執行隊列中原生是先于實現的自己實現暫時用模擬必須傳入并且構造狀態改變之后傳遞的值執行之后返回的這里必須異步處理否
試圖寫了一下,大概測試了一下,沒有用專業的測試工具測試....
代碼感覺還是寫的比較好懂的,本人水平較差,如果測試有問題,歡迎回復指出
地址: https://github.com/julyL/Code...
(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);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82593.html
摘要:今天我們來自己手寫一個符合規范的庫。是異步編程的一種解決方案,比傳統的解決方案回調函數和事件更合理和更強大。我們可以看到,其實就是一個構造函數。所以說我們的數組里存的是一個一個的的回調函數,也就是一個一個。 今天我們來自己手寫一個符合PromiseA+規范的Promise庫。大家是不是很激動呢?? showImg(https://segmentfault.com/img/bV6t4Z?...
摘要:本意是承諾,在程序中的意思就是承諾我過一段時間后會給你一個結果。中采用了規范,實現之前,當然要先了解規范,規范地址。我們根據規范,可以寫一個簡單的庫。每一步都盡量寫的詳細,所以代碼很長很羅嗦。 Promise本意是承諾,在程序中的意思就是承諾我過一段時間后會給你一個結果。 ES6 中采用了 Promise/A+ 規范,Promise 實現之前,當然要先了解 Promise/A+ 規范,...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規范并可配合使用的寫一個符合規范并可配合使用的理解的工作原理采用回調函數來處理異步編程。 JavaScript怎么使用循環代替(異步)遞歸 問題描述 在開發過程中,遇到一個需求:在系統初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...
摘要:本文同時也發布在我的博客上,歡迎之前也手寫過簡單的,這次則是為了通過官方的測試集,借鑒了一些下載量較多的,改了幾遍,終于是通過了規范的個測試用例如何測試測試庫地址在這,大家在寫完自己的后,不妨也去測試一下,檢驗自己的是否符合規范。 本文同時也發布在我的github博客上,歡迎star~ 之前也手寫過簡單的promise,這次則是為了通過官方的Promise A+測試集,借鑒了一些下載量...
摘要:遍歷器原有的表示集合的數據結構,主要有和,在中又加入了和,這樣就有了四種數據集合,還可以組合使用它們,如數組的成員是或,這樣就需要一種統一的接口機制,用來處理所有不同的數據結構。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 閱讀原文 Generators 簡介 Generato...
閱讀 1115·2021-11-23 09:51
閱讀 1081·2021-10-18 13:31
閱讀 2983·2021-09-22 16:06
閱讀 4278·2021-09-10 11:19
閱讀 2204·2019-08-29 17:04
閱讀 433·2019-08-29 10:55
閱讀 2482·2019-08-26 16:37
閱讀 3380·2019-08-26 13:29