1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        如何更好的取消一個promise?

        共 2834字,需瀏覽 6分鐘

         ·

        2021-01-25 13:33

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

        其實就像一個執(zhí)行中的ajax要被取消一樣,ajax有abort()進(jìn)行取消,而且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)傳進(jìn)去。

        改造一下

        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方法的作用,這里還是簡單介紹下。

        當(dāng)有若干個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雖然增加了新的標(biāo)準(zhǔn)實現(xiàn),但仍然存在兼容問題,而且只能在瀏覽器中使用。那么非瀏覽器的環(huán)境中呢?比如RN?所以如果想要達(dá)到一種通用的方式,那么本文的取消promise的方式應(yīng)該是個不錯的方式。

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

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

        點個『在看』支持下?

        瀏覽 118
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            中国日逼视频 | 女上位av片在线观看免费 | 超碰夫妻| 九九导航 | 逼特逼网 | 欧美男同gay巨大男吊 | 六月丁香激情综合色啪小说 | 色五月婷婷av | 中国电影黄色一级片免费观看 | 九九99久久精品在免费线bt |