<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          AbortSignal:以前我沒得選,現(xiàn)在我想中止promise

          共 2126字,需瀏覽 5分鐘

           ·

          2021-10-09 19:25

          作者:卡頌
          來源:SegmentFault 思否社區(qū)


          大家好,我卡頌。

          遙想數年前的一次面試,面試官問我:promise有什么缺點?


          真是百思不得姐啊...

          答案是:promise一旦初始化,就不能中止。這是由promise的實現(xiàn)決定的。

          AbortSignal的出現(xiàn)使promise從語義上變?yōu)榭芍兄沟?。并且,只要符合?guī)范,所有異步操作都能變?yōu)?span style="font-size: 15px;box-sizing: border-box;font-weight: bolder;">可中止的

          AbortSignal是什么

          AbortSignal是個實驗性API,不過兼容性還不錯,而且polyfill實現(xiàn)起來也不復雜。


          AbortSignal可以實例化一個信號對象signal object)。

          AbortController可以實例化一個信號對象的控制器。

          就像遙控器可以發(fā)出信號關電視一樣,AbortController的實例可以控制中止信號。


          只要符合AbortSignal的接入規(guī)范,任何異步操作都能實現(xiàn)中止功能。

          舉個例子,首先new一個控制器實例:

          // 控制器實例
          const controller = new AbortController();
          const signal = controller.signal;

          其中signal是控制器對應的信號對象。

          信號對象可以監(jiān)聽abort事件,當信號被中止時被觸發(fā)。

          調用controller.abort()方法后會中止信號,此時signal.abortedtrue。

          // 監(jiān)聽 abort 事件
          signal.addEventListener('abort', () => {
            console.log("信號中止!")
          });

          // 控制器中止信號
          controller.abort(); 

          console.log('是否中止:', signal.aborted); 

          如上代碼調用后會依次打?。?/span>

          1. 信號中止!
          2. 是否中止:true


          在fetch中的應用

          fetch API已經集成了AbortSignal。
          只需要將controller內的信號對象作為signal參數傳給fetch
          const controller = new AbortController();
          fetch(url, {
            signal: controller.signal
          });
          當調用controller.abort()后,fetchpromise會變?yōu)?/span>AbortError DOMException reject
          fetch('xxxx', {
            signal: controller.signal
          }).then(() => {}, err => {
            if (err.name == 'AbortError') { 
              // 中止信號
            } else {
              // 其他錯誤
            }
          })
          可以在此時處理中止后的操作。
          這里有個取消視頻下載Demo,可以看看fetch如何配合AbortSignal實現(xiàn)取消下載

          與任何異步操作結合

          不僅是fetch,任何異步操作只要符合如下規(guī)范,都可以與AbortError集成:
          1. AbortSignal(信號對象)作為APIsignal參數傳入

          2. 約定如果API返回的promise變?yōu)?/span>AbortError DOMException reject則代表操作被中止

          3. 如果signal.aborted === true則立刻讓promise變?yōu)?/span>reject

          4. 觀測AbortSignal狀態(tài)的變化

          如果API應用場景比較復雜(比如需要考慮多線程通信),文檔中提供了一套基于訂閱發(fā)布abort-algorithms機制來完成步驟4。


          總結

          雖然AbortSignal原理很簡單,但只要遵守接入規(guī)范,他的可擴展性是很強的。
          比如,可以將一個signal傳給多個符合規(guī)范的API,就能用一個控制器中止多個API的調用。
          就像一個遙控器,同時操作家里的空調、電視、洗衣機,你愛了么?


          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“ 入群 ”即可加入我們的技術交流群,收獲更多的技術文章~

          - END -


          瀏覽 23
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美性爱在线观看网站 | 欧美日本黄色一级视频 | 欧美不卡视频 | 777色色色 | 国产精品伦子伦免费 |