久久久久久AV无码免费看大片,亚洲一区精品人人爽人人躁,国产成人片无码免费爱线观看,亚洲AV成人无码精品网站,为什么晚上搞的时候要盖被子

Promise初步詳解(resolve,reject,catch)

時間:2020-12-05 11:18:46 類型:JS/JQUERY
字號:    

  一,何為Promise?

  為了直觀一點,首先我們采用console.dir(Promise)看一下它的結(jié)構(gòu)組成。

     console.dir(Promise);

      1.png

  從上面的圖片中我們可以到,Promise其實是一個構(gòu)造函數(shù)(在JS中,函數(shù)同時也是一個對象),它有resolve,reject,race等靜態(tài)方法;它的原型(prototype)上有then,catch方法,因此只要作為Promise的實例,都可以共享并調(diào)用Promise.prototype上面的方法(then,catch),接下來我們試著使用一下Promise。


  二,Promise的使用

  首先我們來看一下Promise的使用語法:

new Promise(function(resolve,reject){}/*excutor*/);

  在實例化Promise時需要傳入一個函數(shù)excutor作為參數(shù),并且在Promise構(gòu)造函數(shù)執(zhí)行時同步執(zhí)行。廢話不多說,先看一個簡單的實例:

var p = new Promise(function(resolve,reject){
             var timer = setTimeout(function(){
                 console.log('執(zhí)行操作1');
             },1000);
         });

  我們可以看到1s后在控制臺輸出相應(yīng)的結(jié)果,這就說明在實例化過程中,作為參數(shù)的excutor函數(shù)也會執(zhí)行。

  從上面的實例中我們看到,excutor函數(shù)還有兩個參數(shù)resolve和reject,其實這兩個參數(shù)也是函數(shù),在excutor執(zhí)行時被調(diào)用,下面我們具體來談?wù)剅esolve和reject的用法。

  三,resolve和reject的具體用法

  先來說說resolve的用法

  首先我們來看看Promise的幾種狀態(tài):

  pending: 初始狀態(tài),成功或失敗狀態(tài)。

  fulfilled: 意味著操作成功完成。

  rejected: 意味著操作失敗。

        當(dāng)我們在excutor函數(shù)中調(diào)用resolve方法時,Promise的狀態(tài)就變成fulfilled,即操作成功狀態(tài),還記得上面Promise.prototype上面的then和catch方法嗎?當(dāng)Promise狀態(tài)為fullfilled狀態(tài)時執(zhí)行then方法里的操作,注意了,then方法里面有兩個參數(shù)onfulfilled(Promise為fulfilled狀態(tài)時執(zhí)行) 和onrejected(Promise為rejected狀態(tài)時執(zhí)行),步驟如下:

  1,實例化Promise(new Promise(function(resolve,reject)))

  2,用Promise的實例調(diào)用then方法

  具體來看下面的例子:

var p = new Promise(function (resolve, reject) {
            var timer = setTimeout(function () {
                console.log('執(zhí)行操作1');
                resolve('這是數(shù)據(jù)1');
            }, 1000);
        });
        p.then(function (data) {
            console.log(data);
            console.log('這是成功操作');
        });

  簡單的理解就是調(diào)用resolve方法Promise變?yōu)椴僮鞒晒顟B(tài)(fulfilled),執(zhí)行then方法里面onfulfilled里的操作。其實then里面的函數(shù)就是我們平時所說的回調(diào)函數(shù),只不過在這里只是把它分離出來而已。我們可以看到控制臺上的輸出結(jié)果如下所示:

  reject的用法

  看了上面的實例,我相信應(yīng)該也很容易理解reject方法了,就是調(diào)用reject方法后,Promise狀態(tài)變?yōu)閞ejected,即操作失敗狀態(tài),此時執(zhí)行then方法里面onrejected操作,上面我們提到了then方法有兩個參數(shù),一種是Promise狀態(tài)為fulfilled時執(zhí)行(onfullfilled),一種是Promise狀態(tài)為rejected時執(zhí)行(onrejected),其實就是類似于jquery里的hover方法里面的兩個參數(shù)一樣,來看看下面的例子:

var p = new Promise(function (resolve, reject) {
          var flag = false;
          if(flag){
            resolve('這是數(shù)據(jù)2');
          }else{
            reject('這是數(shù)據(jù)2');
          }
        });
        p.then(function(data){//狀態(tài)為fulfilled時執(zhí)行
            console.log(data);
            console.log('這是成功操作');
        },function(reason){ //狀態(tài)為rejected時執(zhí)行
            console.log(reason);
            console.log('這是失敗的操作');
        });

  catch方法

  我們注意到除了then方法外,Promise原型上還有另外一個叫catch的方法,那么這個方法的作用是什么呢?其實跟then方法中的第二個參數(shù)一樣,就是在Promise狀態(tài)為rejected時執(zhí)行,then方法捕捉到Promise的狀態(tài)為rejected,就執(zhí)行catch方法里面的操作,下面用catch方法改寫上面reject用法里面的例子,如下所示:

  var p = new Promise(function (resolve, reject) {
  var flag = false;
  if(flag){
  resolve('這是數(shù)據(jù)2');
  }else{
  reject('這是數(shù)據(jù)2');
  }
  });
  p.then(function(data){
  console.log(data);
  console.log('這是成功操作');
  }).catch(function(reason){
  console.log(reason);
  console.log('這是失敗的操作');
  });

  為什么會有promise,他的作用是什么?

  promise主要是為了解決js中多個異步回調(diào)難以維護和控制的問題.

  四,為何用Promise

  首先我們來看這樣一個例子,取4個定時器,設(shè)置延遲時間都為1s,然后每隔1s依次在控制臺輸出‘我’‘愛’‘米’‘飯’的字樣。代碼如下:

setTimeout(function () {
          console.log('我');
          setTimeout(function () {
              console.log('愛');
              setTimeout(function () {
                  console.log('米');
                  setTimeout(function () {
                      console.log('飯');
                  }, 1000);
              }, 1000);
          }, 1000);
      }, 1000);

  發(fā)現(xiàn)什么問題沒有?是不是有點感覺回調(diào)函數(shù)的嵌套有點多,如果有更多的回調(diào)函數(shù)呢?是不是使代碼的可讀性和可維護性都大大降低了呢(回調(diào)地獄?),這時如果我們使用Promise去實現(xiàn)這個效果,雖然可能代碼不會減少,甚至更多,但是卻大大增強了其可讀性和可維護性。具體看下面例子:

function getStr1() {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve('我');
        }, 1000);
    });
}
function getStr2() {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve('愛');
        }, 1000);
    });
}
function getStr3() {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve('米');
        }, 1000);
    });
}
function getStr4() {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve('飯');
        }, 1000);
    });
}
getStr1().then(function (data) {
    console.log(data);
    return getStr2();
}).then(function (data) {
    console.log(data);
    return getStr3();
}).then(function (data) {
    console.log(data);
    return getStr4();
}).then(function (data) {
    console.log(data);
})

  執(zhí)行效果跟上面一樣,在這個例子中,將得到Promise實例的過程封裝成一個函數(shù)(getStr1,getStr2,getStr3,getStr4)并返回一個Promise實例,再用實例去調(diào)用相應(yīng)的then方法,在每個then方法中通過return得到下一級的Promise實例,比如在第一個Promise實例(getStr1())then方法中,通過return返回下一個Promise對象(getStr2()),然后再去調(diào)用then方法執(zhí)行里面的操作,再返回下一個Promise對象(這里是getStr3()),

  這樣一級一級下去實現(xiàn)了鏈?zhǔn)秸{(diào)用,雖然代碼量增加了,但比起前面的層層嵌套,顯然這種方式使得代碼更易讀更易維護。

  小例子:

function checkFunc() {
let p = new Promise(function (resolve, reject) {
    // 一些比較耗時異步操作
    if(操作完成標(biāo)識) {
        resolve();
    }
});
p.then(function (data) {
    layer.confirm('執(zhí)行下一步操作?', {
        btn: ['確定', '取消']
    }, function () {
       // 確保上面的操作都完成后,才執(zhí)行下面的操作
       // 其他操作...
    });
});
}


<