日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間: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是個實(shí)驗(yàn)性API,不過兼容性還不錯,而且polyfill實(shí)現(xiàn)起來也不復(fù)雜。

AbortSignal可以實(shí)例化一個「信號對象」(signal object)。

AbortController可以實(shí)例化一個「信號對象」的控制器。

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

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

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

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

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

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

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

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

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

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

在fetch中的應(yīng)用

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

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

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

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

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

可以在此時處理中止后的操作。

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

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

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

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

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

總結(jié)

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

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

就像一個遙控器,同時操作家里的空調(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.5511xx.com/article/cdissjc.html