日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
AbortSignal:以前我沒得選,現(xiàn)在我想中止Promise

大家好,我卡頌。

遙想數(shù)年前的一次面試,面試官問我:promise有什么缺點(diǎn)?

真是百思不得姐啊...

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

AbortSignal的出現(xiàn)使promise從語義上變?yōu)榭芍兄沟?。并且,只要符合?guī)范,所有異步操作都能變?yōu)椤缚芍兄沟摹埂?/p>

AbortSignal是什么

AbortSignal是個(gè)實(shí)驗(yàn)性API,不過兼容性還不錯(cuò),而且polyfill實(shí)現(xiàn)起來也不復(fù)雜。

AbortSignal可以實(shí)例化一個(gè)「信號(hào)對(duì)象」(signal object)。

AbortController可以實(shí)例化一個(gè)「信號(hào)對(duì)象」的控制器。

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

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

舉個(gè)例子,首先new一個(gè)控制器實(shí)例:

 
 
 
 
  1. // 控制器實(shí)例 
  2. const controller = new AbortController(); 
  3. const signal = controller.signal; 

其中signal是控制器對(duì)應(yīng)的「信號(hào)對(duì)象」。

「信號(hào)對(duì)象」可以監(jiān)聽abort事件,當(dāng)信號(hào)被中止時(shí)被觸發(fā)。

調(diào)用controller.abort()方法后會(huì)中止信號(hào),此時(shí)signal.aborted為true。

 
 
 
 
  1. // 監(jiān)聽 abort 事件 
  2. signal.addEventListener('abort', () => { 
  3.   console.log("信號(hào)中止!") 
  4. }); 
  5.  
  6. // 控制器中止信號(hào) 
  7. controller.abort();  
  8.  
  9. console.log('是否中止:', signal.aborted);  

如上代碼調(diào)用后會(huì)依次打印:

  1. 信號(hào)中止!
  2. 是否中止:true

在fetch中的應(yīng)用

fetch API已經(jīng)集成了AbortSignal。

只需要將controller內(nèi)的「信號(hào)對(duì)象」作為signal參數(shù)傳給fetch:

 
 
 
 
  1. const controller = new AbortController(); 
  2. fetch(url, { 
  3.   signal: controller.signal 
  4. }); 

當(dāng)調(diào)用controller.abort()后,fetch的promise會(huì)變?yōu)锳bortError DOMException reject:

 
 
 
 
  1. fetch('xxxx', { 
  2.   signal: controller.signal 
  3. }).then(() => {}, err => { 
  4.   if (err.name == 'AbortError') {  
  5.     // 中止信號(hào) 
  6.   } else { 
  7.     // 其他錯(cuò)誤 
  8.   } 
  9. }) 

可以在此時(shí)處理中止后的操作。

這里有個(gè)取消視頻下載Demo[1],可以看看fetch如何配合AbortSignal實(shí)現(xiàn)取消下載

與任何異步操作結(jié)合

不僅是fetch,任何異步操作只要符合如下規(guī)范,都可以與AbortError集成:

  1. 將AbortSignal(信號(hào)對(duì)象)作為API的signal參數(shù)傳入
  2. 約定如果API返回的promise變?yōu)锳bortError DOMException reject則代表操作被中止
  3. 如果signal.aborted === true則立刻讓promise變?yōu)閞eject
  4. 觀測(cè)AbortSignal狀態(tài)的變化

如果API應(yīng)用場(chǎng)景比較復(fù)雜(比如需要考慮多線程通信),文檔中提供了一套基于「訂閱發(fā)布」的abort-algorithms[2]機(jī)制來完成步驟4。

總結(jié)

雖然AbortSignal原理很簡(jiǎn)單,但只要遵守接入規(guī)范,他的可擴(kuò)展性是很強(qiáng)的。

比如,可以將一個(gè)signal傳給多個(gè)符合規(guī)范的API,就能用一個(gè)控制器中止多個(gè)API的調(diào)用。

就像一個(gè)遙控器,同時(shí)操作家里的空調(diào)、電視、洗衣機(jī),你愛了么?

參考資料

[1]取消視頻下載Demo:

https://mdn.github.io/dom-examples/abort-api/[2]abort-algorithms:

https://dom.spec.whatwg.org/#abortsignal-abort-algorithms


分享名稱:AbortSignal:以前我沒得選,現(xiàn)在我想中止Promise
分享地址:http://www.dlmjj.cn/article/cdissjc.html