摘要:試圖寫了一下大概測試了一下沒有用專業(yè)的測試工具測試代碼感覺還是寫的比較好懂的,本人水平較差,如果測試有問題,歡迎回復(fù)指出地址同一執(zhí)行隊列中原生是先于實現(xiàn)的自己實現(xiàn)暫時用模擬必須傳入并且構(gòu)造狀態(tài)改變之后傳遞的值執(zhí)行之后返回的這里必須異步處理否
試圖寫了一下,大概測試了一下,沒有用專業(yè)的測試工具測試....
代碼感覺還是寫的比較好懂的,本人水平較差,如果測試有問題,歡迎回復(fù)指出
地址: 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); // 同一執(zhí)行隊列中,原生Promise是先于setTimeout實現(xiàn)的,自己實現(xiàn)暫時用setTimeout模擬 } } function Promise(fn) { if (!isFunction(fn) || this instanceof Promise == false) { throw new TypeError("Promise必須傳入function并且new構(gòu)造") } this.status = "pending"; this.value = undefined; // promise狀態(tài)改變之后傳遞的值 this.thenPromise = undefined; //執(zhí)行then之后返回的promise this.resolveQueue = []; // this.rejectQueue = []; // var re = asyncExcute(function(resolveData) { this._resolve(resolveData) }.bind(this)), //這里必須異步處理,否則then函數(shù)執(zhí)行以前可能就已經(jīng)執(zhí)行了_resolve,但這時then中函數(shù)還未加入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(()=>{ 出現(xiàn)異常... }).then(refn,rjfn); 出現(xiàn)異常時then還未執(zhí)行, 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") { //執(zhí)行then時,如果狀態(tài)已經(jīng)不是pending,則執(zhí)行相應(yīng)函數(shù) 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 當(dāng) promise 成功執(zhí)行時,所有 onFulfilled 需按照其注冊順序依次回調(diào) handle = this.resolveQueue.shift(); if (!isFunction(handle)) { //不是函數(shù) 2.1.1 onFulfilled 不是函數(shù),其必須被忽略 this.thenPromise.value = resolveData; this.thenPromise.status = "resolve"; this.thenPromise._resolve(); return; } try { //如果 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執(zhí)行,并返回拒因 e returnVal = handle(resolveData); } catch (error) { this.thenPromise.status = "reject"; this.thenPromise.value = error; this.thenPromise._reject(); } if (isObject(returnVal || isFunction(returnVal))) { //如果返回值為對象或者函數(shù) if (returnVal == this.thenPromise) { //如果 promise 和 x 指向同一對象,以 TypeError 為據(jù)因拒絕執(zhí)行 promise this.thenPromise.status = "reject"; this.thenPromise.value = new TypeError("[[Resolve]](promise, x),promise 和 x 不能指向同一對象"); } else if (returnVal instanceof Promise) { //如果 x 為 Promise ,則使 promise 接受 x 的狀態(tài) 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 為對象或者函數(shù) try { //如果取 x.then 的值時拋出錯誤 e ,則以 e 為據(jù)因拒絕 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 當(dāng) promise 成功執(zhí)行時,所有 onFulfilled 需按照其注冊順序依次回調(diào) handle = this.rejectQueue.shift(); if (!isFunction(handle)) { //不是函數(shù) 2.1.1 onFulfilled 不是函數(shù),其必須被忽略 this.thenPromise.value = resolveData; this.thenPromise.status = "resolve"; this.thenPromise._resolve(); return; } try { //如果 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執(zhí)行,并返回拒因 e returnVal = handle(resolveData); } catch (error) { this.thenPromise.status = "reject"; this.thenPromise.value = error; this.thenPromise._reject(); } if (isObject(returnVal || isFunction(returnVal))) { //如果返回值為對象或者函數(shù) if (returnVal == this.thenPromise) { //如果 promise 和 x 指向同一對象,以 TypeError 為據(jù)因拒絕執(zhí)行 promise this.thenPromise.status = "reject"; this.thenPromise.value = new TypeError("[[Resolve]](promise, x),promise 和 x 不能指向同一對象"); } else if (returnVal instanceof Promise) { //如果 x 為 Promise ,則使 promise 接受 x 的狀態(tài) 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 為對象或者函數(shù) try { //如果取 x.then 的值時拋出錯誤 e ,則以 e 為據(jù)因拒絕 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);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82593.html
摘要:今天我們來自己手寫一個符合規(guī)范的庫。是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理和更強大。我們可以看到,其實就是一個構(gòu)造函數(shù)。所以說我們的數(shù)組里存的是一個一個的的回調(diào)函數(shù),也就是一個一個。 今天我們來自己手寫一個符合PromiseA+規(guī)范的Promise庫。大家是不是很激動呢?? showImg(https://segmentfault.com/img/bV6t4Z?...
摘要:本意是承諾,在程序中的意思就是承諾我過一段時間后會給你一個結(jié)果。中采用了規(guī)范,實現(xiàn)之前,當(dāng)然要先了解規(guī)范,規(guī)范地址。我們根據(jù)規(guī)范,可以寫一個簡單的庫。每一步都盡量寫的詳細,所以代碼很長很羅嗦。 Promise本意是承諾,在程序中的意思就是承諾我過一段時間后會給你一個結(jié)果。 ES6 中采用了 Promise/A+ 規(guī)范,Promise 實現(xiàn)之前,當(dāng)然要先了解 Promise/A+ 規(guī)范,...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個接口,可通過...
摘要:本文同時也發(fā)布在我的博客上,歡迎之前也手寫過簡單的,這次則是為了通過官方的測試集,借鑒了一些下載量較多的,改了幾遍,終于是通過了規(guī)范的個測試用例如何測試測試庫地址在這,大家在寫完自己的后,不妨也去測試一下,檢驗自己的是否符合規(guī)范。 本文同時也發(fā)布在我的github博客上,歡迎star~ 之前也手寫過簡單的promise,這次則是為了通過官方的Promise A+測試集,借鑒了一些下載量...
摘要:遍歷器原有的表示集合的數(shù)據(jù)結(jié)構(gòu),主要有和,在中又加入了和,這樣就有了四種數(shù)據(jù)集合,還可以組合使用它們,如數(shù)組的成員是或,這樣就需要一種統(tǒng)一的接口機制,用來處理所有不同的數(shù)據(jù)結(jié)構(gòu)。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 閱讀原文 Generators 簡介 Generato...
閱讀 1107·2021-11-23 09:51
閱讀 1074·2021-10-18 13:31
閱讀 2967·2021-09-22 16:06
閱讀 4256·2021-09-10 11:19
閱讀 2196·2019-08-29 17:04
閱讀 425·2019-08-29 10:55
閱讀 2472·2019-08-26 16:37
閱讀 3369·2019-08-26 13:29