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

資訊專欄INFORMATION COLUMN

Promise對象

琛h。 / 2871人閱讀

摘要:對比回調(diào)函數(shù)和暫時不管是什么,先看一下下面的代碼,看一看的好處?;卣{(diào)函數(shù)執(zhí)行一次首先,定義一個回調(diào)函數(shù),調(diào)用一次,看看這個代碼的寫法。上面的代碼中,在方法中需要傳遞兩個回調(diào)函數(shù),這樣看著會有點亂。

對比回調(diào)函數(shù)和Promise

暫時不管Promise是什么,先看一下下面的代碼,看一看Promise的好處。需要特別說明的是,在這個對比的中,Promise和回調(diào)都沒有考慮存在異常的情況。

回調(diào)函數(shù)執(zhí)行一次

首先,定義一個回調(diào)函數(shù),調(diào)用一次,看看這個代碼的寫法。

"use strict";

// 定義一個計數(shù)器,用來統(tǒng)計回調(diào)函數(shù)執(zhí)行的次數(shù)
let count = 1;

/**
 * 定義一個異步執(zhí)行函數(shù),參數(shù)是回調(diào)函數(shù)
 */
function asyncFunc(callback) {
  setTimeout(function () {
    callback(`callback ... 執(zhí)行了 ${count} 次`);
    count++;
  }, 1000);
};

// 調(diào)用函數(shù)
asyncFunc(function(data){
  console.log(data);
});

/*************************************
callback ... 執(zhí)行了 1 次
*************************************/

如果用Promise改寫,會是什么樣的效果呢?

"use strict";

// 定義一個計數(shù)器,用來統(tǒng)計回調(diào)函數(shù)執(zhí)行的次數(shù)
let count = 1;

/**
 * 定義一個異步執(zhí)行函數(shù),返回值是一個Promise對象
 */
function asyncFunc() {
  let promise = new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(`resolve ... 執(zhí)行了 ${count} 次`);
      count++;
    }, 1000);
  });
  return promise;
};

// 調(diào)用函數(shù)
asyncFunc().then(function(data){
  console.log(data);
});

/*************************************
resolve ... 執(zhí)行了 1 次
*************************************/

怎么感覺代碼更復雜,更加難于理解了?確實,在定義函數(shù)的時候,需要返回一個Promise對象,增加了代碼量,看著沒什么優(yōu)勢。從這點來看,學這個東西,完全沒有必要啊。

別著急,接著往下走。。。。

回調(diào)函數(shù)執(zhí)行多次

上面的情況只是調(diào)用一次函數(shù),那么調(diào)用多次呢?比如調(diào)用個五次、七次。下面咱們看看調(diào)用七次的情況。

首先,還是先看看使用回調(diào)函數(shù)的情況:

"use strict";

// 定義一個計數(shù)器,用來統(tǒng)計回調(diào)函數(shù)執(zhí)行的次數(shù)
let count = 1;

/**
 * 定義一個異步執(zhí)行函數(shù),參數(shù)是回調(diào)函數(shù)
 */
function asyncFunc(callback) {
  setTimeout(function () {
    callback(`callback ... 執(zhí)行了 ${count} 次`);
    count++;
  }, 1000);
};

// 調(diào)用函數(shù)
asyncFunc(function (data) { // 第一次調(diào)用
  console.log(data);
  asyncFunc(function (data) { // 第二次調(diào)用
    console.log(data);
    asyncFunc(function (data) { // 第三次調(diào)用
      console.log(data);
      asyncFunc(function (data) { // 第四次調(diào)用
        console.log(data);
        asyncFunc(function (data) { // 第五次調(diào)用
          console.log(data);
          asyncFunc(function (data) { // 第六次調(diào)用
            console.log(data);
            asyncFunc(function (data) { // 第七次調(diào)用
              console.log(data);
            });
          });
        });
      });
    });
  });
});

/*************************************
callback ... 執(zhí)行了 1 次
callback ... 執(zhí)行了 2 次
callback ... 執(zhí)行了 3 次
callback ... 執(zhí)行了 4 次
callback ... 執(zhí)行了 5 次
callback ... 執(zhí)行了 6 次
callback ... 執(zhí)行了 7 次
*************************************/

看著挺好看,但是,當回調(diào)更多的時候,如何分清是哪個回調(diào),又怎么判斷哪個括號對應(yīng)哪句代碼呢?其實這就是一個回調(diào)地獄,這樣的代碼可讀性差。

這個時候,Promise就可以發(fā)揮作用了。

看了回調(diào)函數(shù),再來看看使用Promise的情況:

"use strict";

// 定義一個計數(shù)器,用來統(tǒng)計回調(diào)函數(shù)執(zhí)行的次數(shù)
let count = 1;

/**
 * 定義一個異步執(zhí)行函數(shù),返回值是一個Promise對象
 */
function asyncFunc() {
  let promise = new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(`resolve ... 執(zhí)行了 ${count} 次`);
      count++;
    }, 1000);
  });
  return promise;
};

// 調(diào)用函數(shù)
asyncFunc() // 第一次調(diào)用
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第二次調(diào)用
  })
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第三次調(diào)用
  })
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第四次調(diào)用
  })
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第五次調(diào)用
  })
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第六次調(diào)用
  })
  .then(function (data) {
    console.log(data);
    return asyncFunc(); // 第七次調(diào)用
  })
  .then(function (data) {
    console.log(data);
  });
  
/*************************************
resolve ... 執(zhí)行了 1 次
resolve ... 執(zhí)行了 2 次
resolve ... 執(zhí)行了 3 次
resolve ... 執(zhí)行了 4 次
resolve ... 執(zhí)行了 5 次
resolve ... 執(zhí)行了 6 次
resolve ... 執(zhí)行了 7 次
*************************************/

會發(fā)現(xiàn),是用了Promise代碼可讀性變得很好,以后也便于修改。

用Promise包裝舊回調(diào)寫法

現(xiàn)在可以看出Promise的好處,如果想以后都使用Promise,可否實現(xiàn)?

肯定可以實現(xiàn)啊,下面就使用Promise來包裝上面的回調(diào)函數(shù)。

使用Promise包裹的時候,只需要經(jīng)過下面幾個步驟:

定義一個函數(shù),返回Promise對象

在Promise對象中調(diào)用異步執(zhí)行函數(shù),參數(shù)是創(chuàng)建Promise對象時傳遞的函數(shù)

"use strict";

// 定義一個計數(shù)器,用來統(tǒng)計回調(diào)函數(shù)執(zhí)行的次數(shù)
let count = 1;

/**
 * 定義一個異步執(zhí)行函數(shù),參數(shù)是回調(diào)函數(shù)
 */
function asyncFunc(callback) {
  setTimeout(function () {
    callback(`callback ... 執(zhí)行了 ${count} 次`);
    count++;
  }, 1000);
};

/**
 * 包裝異步執(zhí)行函數(shù),返回一個Promise對象
 */
function wrapperAsyncFunc() {
  let promise = new Promise(function (resolve, reject) {
    asyncFunc(resolve);
  });
  return promise;
};

// 調(diào)用
wrapperAsyncFunc()
  .then(function (data) {
    console.log(data);
    return wrapperAsyncFunc();
  })
  .then(function (data) {
    console.log(data);
  });
  
/*************************************
callback ... 執(zhí)行了 1 次
callback ... 執(zhí)行了 2 次
*************************************/
認識Promise

在谷歌瀏覽器中,我們看看Promise都包含什么:

方法概述

可以看到,在Promise的prototype上有三個方法,也就是實例對象上有三個方法:

new Promise(function(resolve, reject) { ... } );
promise.then(onFulfilled[, onRejected]);
promise.catch(onRejected);

Promise對象本身的方法,就是靜態(tài)方法:

Promise.all(iterable);
Promise.race(iterable);
Promise.reject(reason);
Promise.resolve();
Promise的三種狀態(tài)

在認識這些方法之前,先認識一下Promise的三種狀態(tài):

pending: 初始狀態(tài),創(chuàng)建Promise成功后的狀態(tài)

fulfilled: 操作執(zhí)行成功后的狀態(tài)

rejected: 操作執(zhí)行失敗后的狀態(tài)

Promise的實例方法

首先,先來創(chuàng)建一個Promise對象,可以根據(jù)num的值,來調(diào)節(jié)執(zhí)行的函數(shù)是resolve還是reject:

new Promise(function(resolve, reject) { ... } );
"use strict";

let num = 3;

// 創(chuàng)建一個Promise對象
let promise = new Promise(function (resolve, reject) {
  if (num > 5) {
    resolve("success ..."); // 操作執(zhí)行成功執(zhí)行的函數(shù)
  } else {
    reject("failure ..."); // 操作執(zhí)行失敗執(zhí)行的函數(shù)
  }
});

首先明確一點,Promise對象創(chuàng)建的時候,立即執(zhí)行??墒牵热皇橇⒓磮?zhí)行,怎么獲取對應(yīng)的狀態(tài)值呢?下面就要使用then方法了。

promise.then(onFulfilled[, onRejected]);
promise.then(function (data) {
  console.log(data);
}, function (reason) {
  console.log(reason);
});

上面的代碼中,在then方法中需要傳遞兩個回調(diào)函數(shù),這樣看著會有點亂。有沒有更優(yōu)的解決方式?有,這個時候要使用catch方法。

// 把上面的代碼進行簡化
promise
  .then(function (data) { // 狀態(tài)變?yōu)閒ulfilled后執(zhí)行的回調(diào)
    console.log(data);
  }).catch(function (reason) { // 狀態(tài)變?yōu)閞ejected后執(zhí)行的回調(diào)
    console.log(reason);
  });
Promise的靜態(tài)方法

為了方法認識Promise.all和Promise.race,定義三個Promise對象:

let promise1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve("promise1 ...");
    console.log("done1 ...");
  }, 2000); // 延遲2秒
});

let promise2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve("promise2 ...");
    console.log("done2 ...");
  }, 4000); // 延遲4秒
});

let promise3 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve("promise3 ...");
    console.log("done3 ...");
  }, 6000); // 延遲6秒
});
Promise.all

Promise.all的作用是在參數(shù)中的所有Promise對象完全執(zhí)行完成的時候,才會執(zhí)行自身的then或catch方法:

Promise
  .all([promise1, promise2, promise3])
  .then(function (data) {
    console.log(data);
  })
  .catch(function (reason) {
    console.log(reason);
  });
 
/***************************************
done1 ...
done2 ...
done3 ...
[ "promise1 ...", "promise2 ...", "promise3 ..." ]
***************************************/

Promise.all中所有的Promise對象狀態(tài)都變?yōu)閒ulfiled狀態(tài)時,才會觸發(fā)then方法;其中一個變?yōu)閞ejected狀態(tài),那么就觸發(fā)catch方法。

需要注意的是,即使觸發(fā)了catch方法,其他的Promise對象中的代碼還是會正常執(zhí)行的。因為這是Promise的特性,創(chuàng)建之后,立即執(zhí)行。

更改一個Promise對象之后,結(jié)果就會成下面的狀態(tài):

let promise2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    reject("promise2 ...");
    console.log("done2 ...");
  }, 4000);
});

/***************************************
done1 ...
done2 ...
promise2 ...
done3 ...
***************************************/
Promise.race

Promise.race的作用是在參數(shù)中的Promise對象中的一個執(zhí)行完成的時候,就會執(zhí)行自身的then或catch方法:

Promise
  .race([promise1, promise2, promise3])
  .then(function (data) {
    console.log(data);
  })
  .catch(function (reason) {
    console.log(reason);
  });

/***************************************
done1 ...
promise1 ...
done2 ...
done3 ...
***************************************/

需要注意的是:Promise.all方法是所有的都執(zhí)行完成才會觸發(fā)then方法,就是不落下任何一個人;而Promise.race方法是有一個執(zhí)行完成就會觸發(fā)then方法,就是看誰跑得快。

后續(xù)的兩個方法,以后用到的時候再補充,因為這些內(nèi)容對現(xiàn)在而言已經(jīng)夠用了。

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

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

相關(guān)文章

  • Promise——從閱讀文檔到簡單實現(xiàn)(一)

    摘要:意味著操作成功完成。方法接收失敗情況的回調(diào)函數(shù)作為參數(shù),返回一個對象。參數(shù)回調(diào)函數(shù)不接收任何參數(shù),當對象變成狀態(tài)時被調(diào)用?,F(xiàn)在各個方法的參數(shù)返回值功能和使用方法已經(jīng)有個大概的了解了,為了進一步理解其原理,接下來我打算簡單地實現(xiàn)一下它。 前言 最近幾周參加筆試面試,總是會遇到實現(xiàn)異步和處理異步的問題,然而作者每次都無法完美地回答。在最近一次筆試因為 Promise 而被刷掉后,我終于下定...

    yanwei 評論0 收藏0
  • 關(guān)于Promise

    摘要:反之,操作失敗,對象由狀態(tài)轉(zhuǎn)換為狀態(tài),此時回調(diào)函數(shù)會執(zhí)行方法。這里需要注意的是,雖然在之后便執(zhí)行了方法,但是并不是意味著往后的對象不執(zhí)行了,其他的還是對象還是要執(zhí)行的,只是不會再調(diào)用函數(shù)。 在 掘金上看見一篇寫promise的文章,感覺作者寫的很棒,文章鏈接在這:八段代碼徹底掌握 Promise 。看完之后感覺學到了很多,所以又重新把JavaScript Promise迷你書(中文版)...

    546669204 評論0 收藏0
  • js-Promise

    摘要:總結(jié)用方法創(chuàng)建對象用或添加對象的處理函數(shù)它的作用是為實例添加狀態(tài)改變時的回調(diào)函數(shù)。方法是的別名,用于指定發(fā)生錯誤時的回調(diào)函數(shù)。 一、為什么需要Promise Javascript 采用回調(diào)函數(shù)(callback)來處理異步編程。從同步編程到異步回調(diào)編程有一個適應(yīng)的過程,但是如果出現(xiàn)多層回調(diào)嵌套,也就是我們常說的回調(diào)金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。于是...

    xcold 評論0 收藏0
  • 簡單學習 Promise 對象

    摘要:方法是的別名,用于指定發(fā)生錯誤時的回調(diào)函數(shù)。由于字符串不屬于異步操作判斷方法是字符串對象不具有方法,返回實例的狀態(tài)從一生成就是,所以回調(diào)函數(shù)會立即執(zhí)行。出錯了等同于出錯了出錯了上面的代碼生成一個對象的實例,狀態(tài)為,回調(diào)函數(shù)會立即執(zhí)行。 引言 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)和事件——更合理且強大。最近的項目要用到這個,就參照阮一峰老師的《ES6標準入門...

    muzhuyu 評論0 收藏0
  • 嘗試實現(xiàn)一個Promise

    摘要:的實現(xiàn)說明沒有執(zhí)行里的函數(shù)說明執(zhí)行了里的函數(shù)說明執(zhí)行里的函數(shù)過程中出現(xiàn)錯誤和執(zhí)行狀態(tài)時的回調(diào)函數(shù)后返回的結(jié)果都需要執(zhí)行傳進來的對象不能等于當前的對象回調(diào)返回的值或者的值是對象時需要等待該對象的狀態(tài)變更設(shè)置當前狀態(tài)的狀態(tài)和值執(zhí)行回調(diào)隊列里的函 function resolve_promise_value(promise,value) {//PromiseA+的實現(xiàn) var th...

    DTeam 評論0 收藏0
  • 關(guān)于promise的小結(jié)

    摘要:則是把類似的異步處理對象和處理規(guī)則進行規(guī)范化,并按照采用統(tǒng)一的接口來編寫,而采取規(guī)定方法之外的寫法都會出錯。這個對象有一個方法,指定回調(diào)函數(shù),用于在異步操作執(zhí)行完后執(zhí)行回調(diào)函數(shù)處理。到目前為止,已經(jīng)學習了創(chuàng)建對象和用,方法來注冊回調(diào)函數(shù)。 Promise 本文從js的異步處理出發(fā),引入Promise的概念,并且介紹Promise對象以及其API方法。 js里的異步處理 可以參考這篇文章...

    Tony_Zby 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<