<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>

          如何更好的取消一個promise?

          共 2834字,需瀏覽 6分鐘

           ·

          2021-01-25 13:33

          一個正在執(zhí)行中的promise怎樣被取消?

          其實就像一個執(zhí)行中的ajax要被取消一樣,ajax有abort()進行取消,而且fetch api 也有了相關(guān)的規(guī)范-【AbortController】。

          fetch 怎樣取消?

          先來看下如何取消一個fetch請求

          const?url?=?"https://bigerfe.com/api/xxxx"
          let?controller;
          let?signal;

          function?requestA(){
          ?if?(controller?!==?undefined)?{
          ????????controller.abort();?//終止請求
          ????}

          ????if?("AbortController"?in?window)?{
          ????????controller?=?new?AbortController;
          ????????signal?=?controller.signal;
          ????}

          ????fetch(url,?{signal})
          ????????.then((response)?=>?{
          ????????????//do?xxx
          ????????????updateAutocomplete()
          ????????})
          ????????.catch((error)?=>?{
          ????????????//do?xxx
          ????????????handleError(error);
          ????????})
          ????});
          }

          怎樣實現(xiàn)實現(xiàn)promise的取消?

          方案1 - 借助reject 方法

          我們都知道一個promise對象狀態(tài)的改變是通過resolve和reject來執(zhí)行的。那是不是可以借助reject方法來模擬呢?

          上代碼

          //返回一個promise和abort方法
          function?getPromise()?{
          ??let?_res,?_rej;
          ??
          ??const?promise?=?new?Promise((resolve,?reject)?=>?{
          ????_res?=?resolve;
          ????_rej?=?reject;
          ????setTimeout(()?=>?{
          ??????resolve('123')
          ????},?5000);
          ??});
          ??return?{
          ????promise,
          ????abort:?()?=>?{
          ??????_rej({
          ????????name:?"abort",
          ????????message:?"the?promise?is?aborted",
          ????????aborted:?true,
          ??????});
          ????}
          ??};
          }

          const?{?promise,?abort?}?=?getPromise();
          promise.then(console.log).catch(e?=>?{
          ??console.log(e);
          });

          abort();

          上面的方法可以正常執(zhí)行,但是不夠通用,可以將Promise構(gòu)造函數(shù)內(nèi)的邏輯提取出來,作為一個回調(diào)傳進去。

          改造一下

          function?getPromise(cb)?{
          ??let?_res,?_rej;
          ??
          ??const?promise?=?new?Promise((res,?rej)?=>?{
          ????_res?=?res;
          ????_rej?=?rej;
          ????cb?&&?cb(res,rej);
          ??});
          ??return?{
          ????promise,
          ????abort:?()?=>?{
          ??????_rej({
          ????????name:?"abort",
          ????????message:?"the?promise?is?aborted",
          ????????aborted:?true,
          ??????});
          ????}
          ??};
          }

          //主邏輯提取出來
          function?runCb(resolve,reject){
          ????setTimeout(()=>{
          ????????resolve('1111')
          ????},3000)
          }

          const?{?promise,?abort?}?=?getPromise(runCb);
          promise.then(console.log).catch(e?=>?{
          ??console.log(e);
          });

          方案2 ?- 借助 Promise.race() 方法

          相信大家都知道race方法的作用,這里還是簡單介紹下。

          當有若干個promise, p1, p2, p3…在調(diào)用, let p = Promise.race([p1, p2, p3,…])的時候,返回的p也是一個promise。那么p什么時候會被resolve或者被reject呢?

          看race我們知道它是競速或賽跑的意思,所以p1, p2, p3 … 最先一個被resolve或者被reject的結(jié)果就是p的resolve或者reject的結(jié)果。所以后續(xù)的promise的resolve和reject都不會再被執(zhí)行了。

          代碼很簡單,其實夠短小精悍。

          //傳入一個正在執(zhí)行的promise
          function?getPromiseWithAbort(p){
          ????let?obj?=?{};
          ????//內(nèi)部定一個新的promise,用來終止執(zhí)行
          ????let?p1?=?new?Promise(function(resolve,?reject){
          ????????obj.abort?=?reject;
          ????});
          ????obj.promise?=?Promise.race([p,?p1]);
          ????return?obj;
          }

          調(diào)用

          var?promise??=?new?Promise((resolve)=>{
          ?setTimeout(()=>{
          ??resolve('123')
          ?},3000)
          })

          var?obj?=?getPromiseWithAbort(promise)

          obj.promise.then(res=>{console.log(res)})

          //如果要取消
          obj.abort('取消執(zhí)行')

          借助race方法明顯的更簡潔,更易用。

          最后

          其實取消promise執(zhí)行和取消請求是一樣的,并不是真的終止了代碼的執(zhí)行,而是對結(jié)果不再處理。另外fetch api雖然增加了新的標準實現(xiàn),但仍然存在兼容問題,而且只能在瀏覽器中使用。那么非瀏覽器的環(huán)境中呢?比如RN?所以如果想要達到一種通用的方式,那么本文的取消promise的方式應該是個不錯的方式。

          目前知名的axios庫也有abort能力,回頭看下它的實現(xiàn)方式,也歡迎小伙伴們留言討論。

          ---end,希望對你有用。

          點個『在看』支持下?

          瀏覽 118
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  亚洲熟女乱色综合亚洲AV | 人人草免费公开视频 | 久久久久女人精品毛片九一 | 极品视觉盛宴 | 国产成人自拍在线 |