成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6學(xué)習(xí)筆記之Promise

zoomdong / 1565人閱讀

摘要:上代碼異步執(zhí)行成功的構(gòu)造函數(shù)接收一個(gè)函數(shù)參數(shù),并傳入兩個(gè)參數(shù),分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。第一個(gè)回調(diào)函數(shù)是對象的狀態(tài)變?yōu)闀r(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是對象的狀態(tài)變?yōu)闀r(shí)調(diào)用。

這篇文章只解決三個(gè)問題。
什么是promise?
promise有什么用?
promise怎么用?

1.什么是promise?

對于ES6來說,就是一個(gè)構(gòu)造函數(shù),可以用new Promise( )來創(chuàng)建Promise實(shí)例。

2.promise有什么用?

先想象兩個(gè)場景:

一,業(yè)務(wù)中,需要請求后臺(tái)的兩個(gè)接口,但是需要第一個(gè)返回成功結(jié)果之后再請求第二個(gè)接口,這是可能會(huì)寫成下面這個(gè)樣子,

    var request  = function(){
        var xhr1 = new XMLHttpRequest();
        xhr1.onreadystatechange = function(){
          if(xhr1.readyState !== 4){
            alert("第一步請求失敗了,請重試!");
            return;
          }
          if(xhr1.status === 200){
            console.log("第一步請求成功了,我們開始下一步吧!");
            var xhr2 = new XMLHttpRequest();
            xhr2.open("GET", url);
            xhr2.onreadystatechange = function(){
              if(xhr2.readyState !== 4){
                alert("第二步請求失敗了,請重試!");
                return;
              }
              if(xhr2.status === 200){
    
                //兩次請求成功后做的一些事情....
    
              } else {
                alert("第二步請求失敗了,請重試!");
              }
            };
            xhr2.responseType = "json";
            xhr2.setRequestHeader("Accept", "application/json2");
            xhr2.send();
          } else {
            alert("第一步請求失敗了,請重試!");
          }
        };
        xhr1.responseType = "json";
        xhr1.setRequestHeader("Accept", "application/json1");
        xhr1.send();
      });
    }
    
    request();

上面代碼用xhr對象實(shí)現(xiàn)了兩次異步請求,代碼很長。不過這僅僅是兩層回調(diào)嵌套,想象一下更多的異步回調(diào)依賴有多可怕…

二,我們都知道,nodejs的一大特點(diǎn)就是事件驅(qū)動(dòng),那就肯定要利用事件的回調(diào)函數(shù)來處理邏輯,多層的回調(diào)嵌套也就在所難免。那么你的代碼很可能就會(huì)寫成這個(gè)德行,

    async(1,function(value){
      async(value,function(value){
        async(value,function(value){
          async(value,function(value){
            async(value,function(value){
              async(value,function(value){
                async(value,function(value){
                  async(value,function(value){
                    async(value,final);
                  });
                });
              });
            });
          });
        });
      });
    })

就此你掉進(jìn)了又長又丑的嵌套地獄。

咋辦?

用promise(回答了“promise是干啥的”)。

咋用?

往下看。

3.promise 怎么用?

在學(xué)習(xí)怎么使用Promise的同時(shí),需要不時(shí)接觸幾個(gè)關(guān)于它的知識(shí)點(diǎn)。能理解最好,理解不了用著用著就理解了。

首先需要了解的是每個(gè)Promise實(shí)例都有三種狀態(tài):

1.進(jìn)行中狀態(tài) pending
2.成功狀態(tài) resolved
3.失敗狀態(tài) rejected

同一時(shí)間下Promise實(shí)例只能有一種狀態(tài),且只能改變一次,改完之后就再也不能變了。

變化的途徑只有兩種,第一,從pending變?yōu)閞esolved;第二,從pending變?yōu)閞ejected。

接下來就一步步的完成一個(gè)promise的使用。

第一步,new一個(gè)Promise實(shí)例。上代碼:

    var promise = new Promise(function(resolve,reject){
      if(/*異步執(zhí)行成功*/){
        resolve(value)
      } else {
        reject(error)
      }
    });

Promise的構(gòu)造函數(shù)接收一個(gè)函數(shù)參數(shù),并傳入兩個(gè)參數(shù)resolve,reject分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。執(zhí)行resolve(),會(huì)將當(dāng)前promise對象的狀態(tài)更改為resolved,執(zhí)行reject()會(huì)將當(dāng)前promise對象的狀態(tài)更改為rejected。

這時(shí)一個(gè)Promise對象已經(jīng)創(chuàng)建完成,異步腳本的結(jié)果也已經(jīng)被存在這個(gè)Promise對象中了,但它是成功是失???我們怎么讀取呢?

第二步,then方法。接著上代碼:

    var promise = new Promise(function(resolve,reject){
      if(/*異步執(zhí)行成功*/){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise.then(function(value){
      console.log(value);
    },function(error){
      console.log(error);
    })

每個(gè)Promise實(shí)例都有一個(gè)then方法,它就是處理Promise中存儲(chǔ)的異步執(zhí)行結(jié)果的方法。then方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù)。第一個(gè)回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽esolved時(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽eject時(shí)調(diào)用。其中,第二個(gè)函數(shù)是可選的,不一定要提供。這兩個(gè)函數(shù)都接受Promise對象傳出的值作為參數(shù)。

需要特別注意的是then方法的返回值還是一個(gè)Promise!這就意味著then方法是支持鏈?zhǔn)秸{(diào)用的。

第三步,catch方法。
catch方法等同于then(null,function(){}),也就是用來處理rejected狀態(tài)下Promise數(shù)據(jù)的。關(guān)于catch個(gè)人認(rèn)為記住兩點(diǎn)就好。第一,用catch來處理rejected的Promise;第二,用catch來捕獲之前所有鏈?zhǔn)秸{(diào)用中拋出的Error對象,注意是所有,包括Promise構(gòu)造函數(shù)、then方法、鏈?zhǔn)秸{(diào)用的then方法、以及之前的catch,這些步驟拋出的錯(cuò)誤都可以被catch捕獲。

    var promise = new Promise(function(resolve,reject){
      if(false){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise
      .then(function(value){
        console.log(value);
      })
      .catch(function(reason){
        console.log(error);
      })

上面代碼會(huì)輸出reject(error)傳入的error值,也就是catch的第一種用法。

    var promise = new Promise(function(resolve,reject){
      if(true){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise
      .then(function(value){
        console.log(value);
        console.log(x);
      })
      .catch(function(reason){
        console.log(reason);
      })

上面代碼會(huì)將Promise的狀態(tài)改為resolved,并執(zhí)行then方法,在then方法中會(huì)拋出一個(gè)x變量未定義的錯(cuò)誤,并由catch方法捕獲到并打印出來,這就是catch的第二個(gè)用法。

至此實(shí)際上我們已經(jīng)學(xué)會(huì)了Promise的基礎(chǔ)應(yīng)用。接下來再學(xué)習(xí)兩個(gè)比較好用的方法。

第一個(gè),Promise.all方法。

該方法能夠并行運(yùn)行異步方法,并在結(jié)果都返回之后進(jìn)行統(tǒng)一處理,并返回一個(gè)新的Promise對象。

    var p = Promise.all([p1, p2, p3]);

上面代碼中,Promise.all方法接受一個(gè)“數(shù)組”作為參數(shù),p1、p2、p3都是Promise對象的實(shí)例。

p的狀態(tài)由p1、p2、p3決定,分成兩種情況。

(1)只有p1、p2、p3的狀態(tài)都變成fulfilled,p的狀態(tài)才會(huì)變成fulfilled,此時(shí)p1、p2、p3的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)。(fulfilled可以理解為resolved)

(2)只要p1、p2、p3之中有一個(gè)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。

    var p = Promise.all([p1,p2,p3]);
    
    p.then(function(results){
        console.log(results)
    });

當(dāng)打開網(wǎng)頁時(shí),需要預(yù)先加載各種資源如圖片、flash以及各種靜態(tài)文件,所有的都加載完后,我們再進(jìn)行頁面的初始化。這種場景是很適合使用Promise.all的。

第二個(gè),Promise.race方法。

與all方法類似,同樣是能夠并行運(yùn)行異步方法,并在結(jié)果都返回之后進(jìn)行統(tǒng)一處理,并返回一個(gè)新的Promise對象。

    var p = Promise.race([p1,p2,p3]);

上面代碼中,只要p1、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給p的回調(diào)函數(shù),也就是說誰執(zhí)行的快就返回誰的。

race方法可以添加請求超時(shí)的限制。

    //請求某個(gè)圖片資源
    
    function requestImg(){
        var p = new Promise(function(resolve, reject){
            var img = new Image();
            img.onload = function(){
                resolve(img);
            }
            img.src = "xxxxxx";
        });
        return p;
    }
    
    //延時(shí)函數(shù),用于給請求計(jì)時(shí)
    
    function timeout(){
        var p = new Promise(function(resolve, reject){
            setTimeout(function(){
                reject("圖片請求超時(shí)");
            }, 5000);
        });
        return p;
    }
    
    Promise
    .race([requestImg(), timeout()])
    .then(function(results){
        console.log(results);
    })
    .catch(function(reason){
        console.log(reason);
    });

到這,關(guān)于Promise的三個(gè)問題已經(jīng)解答完了,希望能夠?yàn)榇蠹覍W(xué)習(xí)Promise提供一點(diǎn)幫助。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82256.html

相關(guān)文章

  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0
  • ES6中的Promise學(xué)習(xí)筆記

    摘要:意味著操作成功完成。當(dāng)調(diào)用方法的時(shí)候會(huì)設(shè)置一個(gè)狀態(tài),調(diào)用方法的時(shí)候會(huì)設(shè)置一個(gè)狀態(tài)。返回是自定義的,狀態(tài)由自己設(shè)但不能不給狀態(tài),不然不會(huì)執(zhí)行下一個(gè)鏈詳細(xì)文檔文檔 背景:在一個(gè)方法中處理一個(gè)復(fù)雜的異步操作時(shí)會(huì)涉及到多個(gè)異步處理,它們可能是層層嵌套導(dǎo)致這個(gè)方法異常的龐大,影響日后的代碼維護(hù)和問題的查找 解決:在ES6中提供了一個(gè)Promise的對象,它以一種鏈?zhǔn)降膶懛▽惒讲僮鬟壿嬇c異步返...

    stefanieliang 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記(四)--------------------------------------pr

    摘要:首先是一個(gè)構(gòu)造器函數(shù),使用它必須通過一個(gè)實(shí)例出來,并且出來的實(shí)例暈有一個(gè)內(nèi)置的參數(shù),這個(gè)參數(shù)是一個(gè)函數(shù),這個(gè)參數(shù)擁有自己內(nèi)置的兩個(gè)參數(shù),和,并且這兩個(gè)參數(shù)也是兩個(gè)函數(shù)異步操作成功上面這個(gè)就是一個(gè)最簡單的對象屬于的一個(gè)方法,里面的兩個(gè)參數(shù)屬于 首先promise是一個(gè)構(gòu)造器函數(shù),使用它必須通過new一個(gè)實(shí)例出來,并且new出來的實(shí)例暈有一個(gè)內(nèi)置的參數(shù),這個(gè)參數(shù)是一個(gè)函數(shù),這個(gè)參數(shù)擁有自己...

    zhaofeihao 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記(四)--------------------------------------pr

    摘要:首先是一個(gè)構(gòu)造器函數(shù),使用它必須通過一個(gè)實(shí)例出來,并且出來的實(shí)例暈有一個(gè)內(nèi)置的參數(shù),這個(gè)參數(shù)是一個(gè)函數(shù),這個(gè)參數(shù)擁有自己內(nèi)置的兩個(gè)參數(shù),和,并且這兩個(gè)參數(shù)也是兩個(gè)函數(shù)異步操作成功上面這個(gè)就是一個(gè)最簡單的對象屬于的一個(gè)方法,里面的兩個(gè)參數(shù)屬于 首先promise是一個(gè)構(gòu)造器函數(shù),使用它必須通過new一個(gè)實(shí)例出來,并且new出來的實(shí)例暈有一個(gè)內(nèi)置的參數(shù),這個(gè)參數(shù)是一個(gè)函數(shù),這個(gè)參數(shù)擁有自己...

    Jochen 評(píng)論0 收藏0
  • Promise源碼學(xué)習(xí)(2)

    摘要:源碼學(xué)習(xí)本篇為上一篇源碼學(xué)習(xí)的補(bǔ)充,主要是來介紹和方法。那個(gè)率先改變的實(shí)例的返回值,就傳遞給的回調(diào)函數(shù)。基本介紹可見阮一峰老師的書籍。的狀態(tài)由決定,分成兩種情況。只有的狀態(tài)都變成,的狀態(tài)才會(huì)變成,此時(shí)的返回值組成一個(gè)數(shù)組,傳遞給的回調(diào)函數(shù)。 Promise源碼學(xué)習(xí)(2) 本篇為上一篇源碼學(xué)習(xí)(1)的補(bǔ)充,主要是來介紹Promise.all()和Promise.race()方法。閑話少敘...

    cfanr 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<