es6 --- 手寫一個promise

一個promise實例:

var getJSON = function(url) {var promise = new Promise(function(resolve, reject) {// XHR對象發現ajax請求var client = new XMLHttpReqeust();client.open("GET", url);client.onreadystatechange = handler;client.responseType = "json";client.setRequestHeader("Accept", "application/json");client.send();function hanlder(){if (this.readyState !== 4) {return;}if (this.status === 200) {resolve(this.response);} else {reject(new Error(this.statusText));}};});return promise;
}
getJSON("/posts.json").then(function(json) {console.log("Content: " + json);
}, function(error) {console.error("出錯了!', error);
});

上述在調用new Promise時,傳遞了一個函數function(resolve, reject),此函數在規范中被稱為exector執行器.
所以,首先:需傳入一個exector執行器:

function Promise(exector) {//...
}

確定Promise內部exector的作用:
可以看出原生的exector中傳入了2個參數,resolve和reject.第一個代表成功,第二個代表失敗.

function Promise(exector) {let self = this;this.value = undefined;this.reason = reason;// 執行成功function resolve(value) {self.value = value;}// 執行失敗function reject(reason) {self.reason = reason;}exector(resolve, reject);
}

添加狀態:
promise的執行過程是不可逆,因此需要一個status來記錄其狀態,初始時為padding,成功了為resolve,失敗了為reject

function Promise(exector) {let self = this;this.status = "padding";this.value = value;this.reason = reason;// 成功function resolve(value) {if(self.status === "padding") {self.value = value;self.status = "resolved";}}// 失敗function  reject(reason) {if(self.status === "padding") {self.reason = reason;self.status = "reject";}}// 對異常的處理try {exector(resolve, reject);} catch(e) {reject(e)}
}

原型上添加then方法:
注意到Promise實例的使用是p.then(onFulfilled, onRejected),可以在前面定義的Promise的原型上添加then方法.

Promise.prototype.then = function(onFulfilled, onRejected) {let self = this;if(this.status === "resolved") {onFulfilled(self.value);}if(this.status === "rejected") {onRejected(self.value);}
}

新增2個數組完成異步操作:
上面編寫的Promise的調用是同步的,但一般都是異步使用Promise,故需在對Promise和其原型進行一定的修改.
如果異步,則處于padding狀態,將回調函數fn保存在數組中!

function Promise(exector) {let self = this;this.status = "padding";this.value = undefined;this.reason = undefined;// 存儲then中成功的回調函數this.onResolvedCallbacks = [];// 存儲then中失敗的回調函數this.onRejectedCallbacks = [];// 成功執行function resolve(value) {if(self.status === "padding") {self.value = value;self.status = "resolved";// 成功后遍歷then中成功的所有回調函數self.onResolvedCallbacks.forEach(fn => fn());}}// 失敗執行function reject(reason) {if(self.status === "padding") {self.reason = reason;self.status = "rejected";// 失敗后遍歷then中失敗的所有回調函數self.onRejectedCallbacks.forEach(fn => fn());}}// 對異常進行處理try {exector(resolve, reject);} catch(e) {reject(e)}
}// Promise.prototype.then
Promise.prototype.then = function(onFulfilled, onRejected) {let self = this;// 成功if (this.status === "resolved") {onFulfilled(self.value);}// 失敗if (this.status === "rejected") {onRejected(self.reason);}// paddingif (this.status === "padding") {// 推進onResolvedCallbacks數組this.onResolvedCallbacks.push( () => {onFulfilled(self.value);})this.onRejectedCallbacks.push( () => {onRejected(self.reason);})}
}

參考《ES6標準入門》(第3版) P276
參考 https://www.jianshu.com/p/4b126518c26d

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251084.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251084.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251084.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

最大流模版 EK

EK算法基于增廣路的思想,易于理解,但由于低效并不被經常使用 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> using namespace std; const int MAXN10005,MAXM100005…

Restrictions查詢用法

Restrictions查詢用法 HQL運算符 QBC運算符 含義 Restrictions.eq() 等于equal <> Restrictions.ne() 不等于not equal > Restrictions.gt() 大于greater than > Restrictions.ge() 大于等于greater than or equal < Restrictions.lt() 小…

chrome調試

技術拓展直播課8 按chrome的官方文檔 長按刷新 清除緩存&#xff08;不一定好使&#xff09; Ctrl f 查找類 console控制臺見b站 bilibili source面板直接打斷點 效果和debugger一樣 單步調試 進入到函數的下一步 網速 no throttling 是否需要過濾 domcontentloaded d…

es6 --- promise和async/await的區別

首先需要了解async函數: async是Generator函數的語法糖: // 使用Generator依次讀取兩個文件 var fs require(fs); var readFile function (fileName) {return new Promise(function (resolve, reject) {fs.readFile(filename, function(error, data) {if (error) return re…

Ueditor百度編輯器中的 setContent()方法的使用

百度編輯器Ueditor所提供的setContent()方法作用是&#xff1a;設置或者改變編輯器里面的文字內容或html內容 函數說明&#xff1a;setContent(string,boolean); 參數string 是需要設置到編輯器里面的內容&#xff0c;可以含有HTML代碼&#xff0c;最后插入到編輯器中的內容是經…

小程序UI

從input組件說起 <input maxlength"10" placeholder"最大輸入長度10" /> <div id"wrapper" disabled$"{{disabled}}">\n <p id"placeholder" class$"{{_getPlaceholderClass(placeholderClass)}}"…

61-1 認識webpack

認識webpack 面向過程開發的不便引入外部js執行順序面向對象開發 加載多個文件耗時更多 增加了http請求 引入過多js變量來源不明 優化 使用前先import 但使用import語法需要借助工具webpack翻譯為瀏覽器可以解析的語法安裝node自動攜帶npmwebpack若沒有全局安裝 需要使用npx…

css font簡寫

一、字體屬性主要包括下面幾個 font-family&#xff0c;font-style&#xff0c;font-variant&#xff0c;font-weight&#xff0c;font-size&#xff0c;fontfont-family&#xff08;字體族&#xff09;: “Arial”、“Times New Roman”、“宋體”、“黑體”等;font-style&…

javascript --- 原生的拖拽功能實現

準備一個方塊: <style>.drag{background-color:#aaf;position:absolute;} </style> <div class"drag" style"width:100px;height:100px;top:0;left:0"></div>監聽鼠標的按住事件: let dragDiv document.getElementsByClassName…

web安全學習-驗證機制存在的問題

驗證機制是應用程序防御惡意攻擊的中心機制。它處于防御未授權的最前沿&#xff0c;如果用戶能夠突破那些防御&#xff0c;他們通常能夠控制應用程序的全部功能&#xff0c;自由訪問其中的數據。缺乏安全穩定的驗證機制&#xff0c;其他核心安全機制&#xff08;如回話管理和訪…

ES5-拓展 原型鏈、繼承、類

Symbol不是構造函數 Object不是原型是實例對象 他的構造器繼承原型上的構造器 undefined是未定義 null是空指針 一、原型鏈 1. 函數也是實例對象 2. 構造函數Object是由Function構造出來的 3. 有一種說法是&#xff0c;原型鏈的終點是null Object.prototype.__proto__指向nul…

Mysql中各種與字符編碼集(character_set)有關的變量含義

mysql涉及到各種字符集&#xff0c;在此做一個總結。 字符集的設置是通過環境變量來設置的&#xff0c;環境變量和linux中的環境變量是一個意思。mysql的環境變量分為兩種&#xff1a;session和global。session變量是僅在這次會話紅中有效&#xff0c;在mysql中&#xff0c;一次…

spring boot 加載application配置文件

這就要注意了 轉載于:https://www.cnblogs.com/huochaihe/p/9397849.html

javascript --- 防抖與節流

先做一個監聽鼠標移動的base: <style>#content{height:150px;width:200px;text-align:center;color:#fff;background-color:#ccc;font-size: 70px;} </style> <div id"content"></div> <script>let content document.getElementById…

DOM-9 【實戰】模塊化開發Todolist(面向過程)

模塊化分類 按dom結構劃分按功能劃分&#xff08;組件化開發&#xff09; 模塊與模塊之間可以相互依賴&#xff0c;但互不影響 模塊&#xff1a;IIFE賦值給一個變量&#xff0c;當引入模塊時&#xff0c;IIFE會立即執行 單標簽閉合才符合W3C規范display、position放在上面css是…

mysql在linux下的安裝(5.7版本以后)

1.添加mysql組和mysql用戶&#xff0c;用于設置mysql安裝目錄文件所有者和所屬組。 ①groupadd mysql ②useradd -r -g mysql mysql 2.將二進制文件解壓到指定的安裝目錄&#xff0c;通用的/usr/local ①解壓二進制文件&#xff0c; tar -zxvf /usr/local/mysql-5.7.13-linux-…

Kali Linux2018 上安裝open-vm-tools實現虛擬機交互

最新的kali linux2018已經不再支持原有的vmwaretools&#xff0c;即使安裝了也不能實現主機與客戶機之間的交互&#xff08;比如從主機復制文件到客戶機&#xff09;。安裝open-vm-tools替代vm tools能夠完美實現“自動適應客戶機”&#xff08;即自動適應客戶機的分辨率&#…

DOM-11 【兼容】鼠標行為坐標系、pageXY封裝、拖拽函數封裝

鼠標行為 e.屬性含義相關屬性clientX/Y鼠標位置相對于當前可視區域的坐標x/y&#xff08;FF火狐部分版本不支持&#xff09;pageX/Y(IE9以下不支持)鼠標位置相對于當前文檔的坐標layerX/Y (IE11以下同clientX/Y)screenX/Y鼠標位置相對于顯示器屏幕的坐標offsetX/Y鼠標位置相對…

java --replaceAll方法

public void abc(){String str "aabbccdd";str str.replaceAll("\\d","數字")&#xff1b;system.out.println("str"); } 轉載于:https://www.cnblogs.com/gjack/p/8325778.html

mysql分頁優化

一般分頁這樣寫 select * from goods limit 50,20 從50行開始取20行&#xff0c;即第51行到70行 當數據量少當時候這樣并沒有什么問題&#xff0c;但是如果 select * from goods limit 1000000,20 查詢耗時驟升。 這種方式是查詢出100000020行&#xff0c;再取20行&#xff0c;…