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