• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    理解JavaScript中Promise的使用_javascript技巧

    來源:懂視網 責編:小采 時間:2020-11-27 21:48:55
    文檔

    理解JavaScript中Promise的使用_javascript技巧

    理解JavaScript中Promise的使用_javascript技巧:Javascript 采用回調函數(callback)來處理異步編程。從同步編程到異步回調編程有一個適應的過程,但是如果出現多層回調嵌套,也就是我們常說的厄運的回調金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。于是便有了 CommonJS 的 Promis
    推薦度:
    導讀理解JavaScript中Promise的使用_javascript技巧:Javascript 采用回調函數(callback)來處理異步編程。從同步編程到異步回調編程有一個適應的過程,但是如果出現多層回調嵌套,也就是我們常說的厄運的回調金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。于是便有了 CommonJS 的 Promis

    Javascript 采用回調函數(callback)來處理異步編程。從同步編程到異步回調編程有一個適應的過程,但是如果出現多層回調嵌套,也就是我們常說的厄運的回調金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。于是便有了 CommonJS 的 Promises/A 規范,用于解決回調金字塔問題。本文先介紹 Promises 相關規范,然后再通過解讀一個迷你的 Promises 以加深理解。

    什么是 Promise
    一個 Promise 對象代表一個目前還不可用,但是在未來的某個時間點可以被解析的值。它允許你以一種同步的方式編寫異步代碼。例如,如果你想要使用 Promise API 異步調用一個遠程的服務器,你需要創建一個代表數據將會在未來由 Web 服務返回的 Promise 對象。唯一的問題是目前數據還不可用。當請求完成并從服務器返回時數據將變為可用數據。在此期間,Promise 對象將扮演一個真實數據的代理角色。接下來,你可以在 Promise 對象上綁定一個回調函數,一旦真實數據變得可用這個回調函數將會被調用。

    Promise 對象曾經以多種形式存在于許多語言中。

    去除厄運的回調金字塔(Pyramid of Doom)
    Javascript 中最常見的反模式做法是回調內部再嵌套回調。

    引入 Promises 之后的代碼

    Promises 將嵌套的 callback,改造成一系列的.then的連綴調用,去除了層層縮進的糟糕代碼風格。Promises 不是一種解決具體問題的算法,而已一種更好的代碼組織模式。接受新的組織模式同時,也逐漸以全新的視角來理解異步調用。

    各個語言平臺都有相應的 Promise 實現

  • Java's java.util.concurrent.Future
  • Python's Twisted deferreds and PEP-3148 futures
  • F#'s Async
  • .Net's Task
  • C++ 11's std::future
  • Dart's Future
  • Javascript's Promises/A/B/D/A+
  • 下面我來相信了解一下 javascript 語言環境下各個規范的一些細節。

    Promises/A 規范
    promise 表示一個最終值,該值由一個操作完成時返回。

  • promise 有三種狀態:**未完成** (unfulfilled),**完成** (fulfilled) 和**失敗** (failed)。
  • promise 的狀態只能由**未完成**轉換成完成,或者**未完成**轉換成**失敗** 。
  • promise 的狀態轉換只發生一次。
  • promise 有一個 then 方法,then 方法可以接受 3 個函數作為參數。前兩個函數對應 promise 的兩種狀態 fulfilled 和 rejected 的回調函數。第三個函數用于處理進度信息(對進度回調的支持是可選的)。

    如果 promise 支持如下連個附加方法,稱之為可交互的 promise

  • get(propertyName)
  • 獲得當前 promise 最終值上的一個屬性,返回值是一個新的 promise。

  • call(functionName, arg1, arg2, ...)
  • 調用當然 promise 最終值上的一個方法,返回值也是一個新的promise。

    Promises/B 規范
    在 Promises/A 的基礎上,Promises/B 定義了一組 promise 模塊需要實現的 API

    when(value, callback, errback_opt)
    如果 value 不是一個 promise ,那么下一事件循環callback會被調用,value 作為 callback 的傳入值。如果 value 是一個 promise,promise 的狀態已經完成或者變成完成時,那么下一事件循環 callback 會被調用,resolve 的值會被傳入 callback;promise 的狀態已經失敗或者變成失敗時,那么下一事件循環 errback 會被調用,reason 會作為失敗的理由傳入 errback。

    asap(value, callback, errback_opt)
    與 when 最大的區別,如果 value 不是一個 promise,會被立即執行,不會等到下一事件循環。

    enqueue(task Function)
    盡可能快地在接下來的事件循環調用 task 方法。

    get(object, name)
    返回一個獲得對象屬性的 promise。

    post(object, name, args)
    返回一個調用對象方法的 promise。

    put(object, name, value)
    返回一個修改對象屬性的 promise。

    del(object, name)
    返回一個刪除對象屬性的 promise。

    makePromise(descriptor Object, fallback Function)
    返回一個 promise 對象,該對象必須是一個可調用的函數,也可能是可被實例化的構造函數。

  • 第一個參數接受一個描述對象,該對象結構如下,
  • 上面每一個注冊的 handle 都返回一個 resolved value或者 promise。

  • 第二個參數接受一個 fallback(message,...args) 函數,當沒有 promise 對象沒有找到對應的 handle 時該函數會被觸發,返回一個 resolved value 或者 promise。
  • defer()
    返回一個對象,該對象包含一個 resolve(value) 方法和一個 promise 屬性。
    當 resolve(value) 方法被第一次調用時,promise 屬性的狀態變成 完成,所有之前或之后觀察該 promise 的 promise 的狀態都被轉變成 完成。value 參數如果不是一個 promise ,會被包裝成一個 promise 的 ref。resolve 方法會忽略之后的所有調用。

    reject(reason String)
    返回一個被標記為 失敗 的 promise。
    一個失敗的 promise 上被調用 when(message) 方法時,會采用如下兩種方法之一
    1. 如果存在 errback,errback 會以 reason 作為參數被調用。when方法會將 errback 的返回值返回。
    2. 如果不存在 errback,when 方法返回一個新的 reject 狀態的promise 對象,以同一 reason 作為參數。

    ref(value)
    如果 value 是 promise 對象,返回 value 本身。否則,返回一個resolved 的 promise,攜帶如下 handle。
    1. when(errback),忽略 errback,返回 resolved 值
    2. get(name),返回 resolved 值的對應屬性。
    3. put(name, value) ,設置 resolved 值的對應屬性。
    4. del(name),刪除 resolved 值的對應屬性。
    5. post(name, args), 調用 resolved 值的對應方法。
    6. 其他所有的調用都返回一個 reject,并攜帶 "Promise does not handle NAME" 的理由。

    isPromise(value) Boolean
    判斷一個對象是否是 promise

    method(name String)
    獲得一個返回 name 對應方法的 promise。返回值是 "get", "put", "del" 和 "post" 對應的方法,但是會在下一事件循環返回。

    Promises/D 規范
    為了增加不同 promise 實現之間的可互操作性,Promises/D 規范對promise 對象和 Promises/B 規范做了進一步的約定。以達到鴨子類型的效果(Duck-type Promise)。

    簡單來說Promises/D 規范,做了兩件事情,

    1、如何判斷一個對象是 Promise 類型。
    2、對 Promises/B 規范進行細節補充。
    甄別一個 Promise 對象
    Promise 對象必須是實現 promiseSend 方法。
    1. 在 promise 庫上下文中,如果對象包含 promiseSend 方法就可以甄別為promise 對象
    2. promiseSend 方法必須接受一個操作名稱,作為第一個參數
    3. 操作名稱是一個可擴展的集合,下面是一些保留名稱
    1. when,此時第三個參數必須是 rejection 回調。
    1. rejection回調必須接受一個 rejection 原因(可以是任何值)作為第一個參數
    2. get,此時第三個參數為屬性名(字符串類型)
    3. put,此時第三個參數為屬性名(字符串類型),第四個參數為新屬性值。
    4. del,此時第三個參數為屬性名
    5. post,此時第三個參數為方法的屬性名,接下來的變參為方法的調用參數
    6. isDef
    4. promiseSend方法的第二個參數為 resolver 方法
    5. promiseSend方法可能接受變參
    6. promiseSend方法必須返回undefined

    對 Promises/B 規范的補充
    Promises/D 規范中對 Promises/B 規范中定義的ref、reject、def、defer方法做了進一步細致的約束,此處略去這些細節。

    Promises/A+ 規范
    前面提到的 Promises/A/B/D 規范都是有CommonJS組織提出的,Promises/A+是有一個自稱為Promises/A+ 組織發布的,該規范是以Promises/A作為基礎進行補充和修訂,旨在提高promise實現之間的可互操作性。

    Promises/A+ 對.then方法進行細致的補充,定義了細致的Promise Resolution Procedure流程,并且將.then方法作為promise的對象甄別方法。

    此外,Promises/A+ 還提供了兼容性測試工具,以確定各個實現的兼容性。

    實現一個迷你版本的Promise
    上面扯了這么多規范,現在我們看看如何實現一個簡單而短小的Promise。

    1、狀態機

    2、狀態變遷
    僅支持兩種狀態變遷,fulfill和reject

    fulfill和reject方法較為底層,通常更高級的resolve方法開放給外部。

    resolve方法可以接受一個普通值或者另一個promise作為參數,如果接受一個promise作為參數,等待其完成。promise不允許被另一個promise fulfill,所以需要開放resolve方法。resolve方法依賴一些幫助方法定義如下:

    這里resolve和doResolve之間的遞歸很巧妙,用來處理promise的層層嵌套(promise的value是一個promise)。

    構造器

    .done方法

    .then方法

    $.promise
    jQuery 1.8 之前的版本,jQuery的 then 方法只是一種可以同時調用 done 、fail 和 progress 這三種回調的速寫方法,而 Promises/A 規范的 then 在行為上更像是 jQuery 的 pipe。 jQuery 1.8 修正了這個問題,使 then 成為 pipe 的同義詞。不過,由于向后兼容的問題,jQuery 的 Promise 再如何對 Promises/A 示好也不太會招人待見。

    此外,在 Promises/A 規范中,由 then 方法生成的 Promise 對象是已執行還是已拒絕,取決于由 then 方法調用的那個回調是返回值還是拋出錯誤。在 JQuery 的 Promise 對象的回調中拋出錯誤是個糟糕的主意,因為錯誤不會被捕獲。

    小結
    最后一個例子揭示了,實現 Promise 的關鍵是實現好 doResolve 方法,在完事以后觸發回調。而為了保證異步 setTimeout(fun, 0); 是關鍵一步。

    Promise 一直用得蠻順手的,其很好的優化了 NodeJS 異步處理時的代碼結構。但是對于其工作原理卻有些懵懂和好奇,于是花了些精力查閱并翻譯了Promise 的規范,以充分的理解 Promise 的細節。

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    理解JavaScript中Promise的使用_javascript技巧

    理解JavaScript中Promise的使用_javascript技巧:Javascript 采用回調函數(callback)來處理異步編程。從同步編程到異步回調編程有一個適應的過程,但是如果出現多層回調嵌套,也就是我們常說的厄運的回調金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。于是便有了 CommonJS 的 Promis
    推薦度:
    標簽: js 理解 javascript
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 精品午夜久久福利大片| 亚洲国产精品成| 国产日韩一区在线精品欧美玲| 国内精品久久久久国产盗摄| 凹凸国产熟女精品视频app | 久久久精品久久久久特色影视| 第一福利永久视频精品| 无码人妻精品一区二区三区66| 久久久久这里只有精品 | 亚洲国产精品尤物YW在线观看| 成人精品一区二区三区免费看 | 无码AV动漫精品一区二区免费| 国产精品久久久久久久久久免费| 久久久精品2019免费观看| 99久久精品国产毛片| 国产69精品久久久久777| 亚洲动漫精品无码av天堂| 免费精品久久久久久中文字幕| 99热精品久久只有精品| 久久se精品一区二区| 99国产欧美精品久久久蜜芽| 久久精品黄AA片一区二区三区| 亚洲精品无码专区在线在线播放| 国产中老年妇女精品| 亚洲愉拍99热成人精品热久久| 久久精品国产亚洲精品| 国产一区麻豆剧传媒果冻精品| 国产精品美女网站| 国产精品免费αv视频| 国产精品视频不卡| 国产精品高清免费网站| 国产精品免费久久久久久久久| 国产观看精品一区二区三区| 国产精品粉嫩美女在线观看| 国产A∨国片精品一区二区| 成人午夜精品久久久久久久小说 | 亚洲精品国产V片在线观看 | 一本大道久久a久久精品综合| 99精品一区二区三区无码吞精| 999久久久无码国产精品| 国产午夜精品一区二区三区漫画|