摘要:將其加入規(guī)范,也修改實現(xiàn)向規(guī)范靠攏發(fā)布公告。封裝接下來開始封裝。使用剛才封裝好的函數(shù)接下來就可以在項目中使用了支持兩個參數(shù),第一個在成功時啟動,第二個自然在失敗時啟動。
我近期在 SF 做了一場關于 Promise 的專題分享,做的很用心,內(nèi)容也很豐富,基本可以一站式解決所有關于 Promise 的問題。歡迎大家前來圍觀:
Promise 的 N 種用法
Promise 在處理異步的時候是個很好的選擇,可以減少嵌套層次,讓代碼更好讀,邏輯更清晰。ES6 將其加入規(guī)范,jQuery 3.0 也修改實現(xiàn)向規(guī)范靠攏(3.0 發(fā)布公告)。一些新增元素比如 .fetch() 原生就 “thenable”,不過大多數(shù)以往的 API 還要依賴回調(diào),這個時候,我們只要將它們重新封裝,就能避開嵌套陷阱,享受 Promise 帶來的愉悅體驗。
Promise 一般用法先來看下 Promise 的一般用法。
// 聲明 Promise 對象 var p = new Promise(function (resolve, reject) { // 不管啥時候,該執(zhí)行then了,就調(diào)用 resolve setTimeout(function () { resolve(1); }, 5000); // 或者不管啥問題,就調(diào)用 reject if (somethingWrong) { reject("2"); } }); // 使用 Promise 對象 p.then(function (num) { // 對應上面的 resolve console.log(num); // 1 }, function (num) { // 對應上面的 reject console.log(num); // 2 });
Promise 的驅(qū)動模型并不復雜:任何操作,假定它只有兩個結(jié)果,成功或者失敗。那么只需要在合適的時間調(diào)用合適的程序,進入合適的后續(xù)步驟即可。.then() 顧名思義,就是下一步的意思,當前面的 Promise 有了結(jié)果——即調(diào)用 resolve 或者 reject——之后,就啟動對應的處理函數(shù)。
Promise 實例創(chuàng)建后就會開始執(zhí)行,判定結(jié)果需要我們自己來,比如加載成功,或者滿足某個條件,等等。通過串聯(lián) .then() 則可以完成一系列操作。每次調(diào)用 .then() 都會創(chuàng)建一個新的 Promise 實例,它會靜靜等待前面的實例狀態(tài)改變后再開始執(zhí)行。
封裝 FileReader接下來開始封裝。思路很簡單,FileReader 除了提供各種 read 方法,還有幾個事件鉤子,其中 onerror 和 onload 很明顯可以作為判斷任務是否完成的依據(jù)。加載成功的話,就需要用到文件內(nèi)容,所以將文件或文件內(nèi)容傳遞到下一步也十分必要。
最后完成的代碼如下:
function reader (file, options) { options = options || {}; return new Promise(function (resolve, reject) { let reader = new FileReader(); reader.onload = function () { resolve(reader); }; reader.onerror = reject; if (options.accept && !new RegExp(options.accept).test(file.type)) { reject({ code: 1, msg: "wrong file type" }); } if (!file.type || /^text//i.test(file.type)) { reader.readAsText(file); } else { reader.readAsDataURL(file); } }); }
為了能真正派上用場,里面還有一些驗證文件類型的操作,不過跟本文主旨無關,略過不表。這段代碼的核心是創(chuàng)建一個 Promise 對象,等待 FileReader 讀取完成后調(diào)用 resolve 方法,或者出現(xiàn)問題時調(diào)用 reject 方法。
Github Gist 里也放了一份。
使用剛才封裝好的函數(shù)接下來就可以在項目中使用了:
reader(file) .then(function (reader) { console.log(reader.result); }) .catch(function (error) { console.log(error); });
.then() 支持兩個參數(shù),第一個在 Promise 成功時啟動,第二個自然在失敗時啟動。用 .catch() 可以實現(xiàn)同樣地效果。Promise 的好處除了可讀性更佳以外,返回的 Promise 對象還可以任意傳遞,繼續(xù)進行鏈式調(diào)用,有很大想象空間。
繼續(xù) .then()于是我們不妨串聯(lián)更多操作(本來想寫個斷點續(xù)傳的,回頭再說吧):
reader(file) .then(function (reader) { return new Promise(function (resolve, reject) { // 就隨便暫停個5秒吧…… setTimeout(function () { resolve(reader.result); }, 5000); }); }) .then(function (content) { console.log(content); });總結(jié)
這其實是我第一次用 Promise,上次翻譯 jQuery 發(fā)布公告的時候我它也只是一知半解,對它的解讀也糊里糊涂。我很喜歡在業(yè)余項目中學習使用新技術,最近開發(fā) Chrome 插件的時候就嘗試了一把,感覺不錯。使用過程比我想象的復雜也比我想象的簡單,這套設計很棒,能解決不少實際問題,也給了我很大啟發(fā),將來我應該會把很多地方的實現(xiàn)都做這樣的修改。
參考文獻除去第一段的各個鏈接,還有一些文章值得一看。
ECMAScript 6 入門:Promise 對象
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/78676.html
摘要:對于第二種存儲方式,我們前端需要將其二進制流交由對象處理,然后通過的生成臨時賦值給屬性來顯示。當后端返回特定的圖片二進制流的時候,就像我第一里的情景再現(xiàn)說的,前端用容器接收。 前言 作為前端工程師 de 我們,日常少不了會跟圖片打交道。在各大電商平臺工作的前端工程師們,感受可能會更加的明顯。 以下是我之前跟圖片打交道踩到的坑,跟大家分享一下經(jīng)驗。 一、情景再現(xiàn) 用postman請求接口...
摘要:對于第二種存儲方式,我們前端需要將其二進制流交由對象處理,然后通過的生成臨時賦值給屬性來顯示。當后端返回特定的圖片二進制流的時候,就像我第一里的情景再現(xiàn)說的,前端用容器接收。 前言 作為前端工程師 de 我們,日常少不了會跟圖片打交道。在各大電商平臺工作的前端工程師們,感受可能會更加的明顯。 以下是我之前跟圖片打交道踩到的坑,跟大家分享一下經(jīng)驗。 一、情景再現(xiàn) 用postman請求接口...
摘要:對于第二種存儲方式,我們前端需要將其二進制流交由對象處理,然后通過的生成臨時賦值給屬性來顯示。當后端返回特定的圖片二進制流的時候,就像我第一里的情景再現(xiàn)說的,前端用容器接收。 前言 作為前端工程師 de 我們,日常少不了會跟圖片打交道。在各大電商平臺工作的前端工程師們,感受可能會更加的明顯。 以下是我之前跟圖片打交道踩到的坑,跟大家分享一下經(jīng)驗。 一、情景再現(xiàn) 用postman請求接口...
摘要:背景前一陣子開發(fā)的項目導入由于自己的代碼問題引起了個性能問題一個的文件轉(zhuǎn)換成數(shù)據(jù)大概要耗時雖然后面發(fā)現(xiàn)是某個使用頻率非常高的函數(shù)內(nèi)部用了構(gòu)造函數(shù)造成的所以這里順便提醒一下如果你很在乎幾毫秒的差距的話建議謹慎使用哈但是在優(yōu)化的過程中一度懷疑是 背景 前一陣子開發(fā)的項目 pptx 導入, 由于自己的代碼問題,引起了個性能問題,一個 40p 的 pptx 文件,轉(zhuǎn)換成 json 數(shù)據(jù),大概要...
閱讀 3489·2023-04-25 22:04
閱讀 2244·2021-11-22 15:29
閱讀 2231·2021-10-11 10:57
閱讀 1482·2021-09-24 09:48
閱讀 3200·2021-09-09 09:34
閱讀 2626·2021-09-02 15:21
閱讀 2449·2019-08-30 15:53
閱讀 1191·2019-08-30 14:07