最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Javascript ES6中的原生Promise

 更新時間:2016年08月25日 08:52:27   投稿:daisy  
ES6標準出爐之前,一個幽靈,回調的幽靈,游蕩在JavaScript世界。正所謂世界本沒有回調,寫的人多了也就有了。接下來就來簡單介紹Javascript ES6中的原生Promise,有需要的可以參考借鑒。

前言

一個 Promise 對象可以理解為一次將要執(zhí)行的操作(常常被用于異步操作),使用了 Promise 對象之后可以用一種鏈式調用的方式來組織代碼,讓代碼更加直觀。而且由于 Promise.all 這樣的方法存在,可以讓同時執(zhí)行多個操作變得簡單。

Promise的興起,是因為異步方法調用中,往往會出現(xiàn)回調函數(shù)一環(huán)扣一環(huán)的情況。這種情況導致了回調金字塔問題的出現(xiàn)。不僅代碼寫起來費勁又不美觀,而且問題復雜的時候,閱讀代碼的人也難以理解。

舉例如下:

db.save(data, function(data){
 // do something...
 db.save(data1, function(data){
 // do something...
 db.save(data2, function(data){
  // do something...
  done(data3); // 返回數(shù)據(jù)
 })
 });
});

假設有一個數(shù)據(jù)庫保存操作,一次請求需要在三個表中保存三次數(shù)據(jù)。那么我們的代碼就跟上面的代碼相似了。這時候假設在第二個db.save出了問題怎么辦?基于這個考慮,我們又需要在每一層回調中使用類似try...catch這樣的邏輯。這個就是萬惡的來源,也是node剛開始廣為詬病的一點。

另外一個缺點就是,假設我們的三次保存之間并沒有前后依賴關系,我們仍然需要等待前面的函數(shù)執(zhí)行完畢, 才能執(zhí)行下一步,而無法三個保存并行,之后返回一個三個保存過后需要的結果。(或者說實現(xiàn)起來需要技巧)

不幸的是,在我剛開始接觸node的時候,我寫了大量這樣的hell。

后來因為還是寫前端代碼多一些,我接觸了ES6,發(fā)現(xiàn)了一個解決回調深淵的利器Promise。

其實早在ES6的Promise之前,Q,when.js,bluebird等等庫早就根據(jù)Promise標準(參考Promise/A+)造出了自己的promise輪子。
(看過一篇文章,我覺得很有道理。里面說,不要擴展內置的原生對象。這種做法是不能面向未來的。所以這里有一個提示:使用擴展原生Promise的庫時,需要謹慎。)

這里僅討論原生的Promise。

ES6 Promise

Promise對象狀態(tài)

在詳解Promise之前,先來點理論:

Promise/A+規(guī)范, 規(guī)定Promise對象是一個有限狀態(tài)機。

它三個狀態(tài):

     1、pending(執(zhí)行中)

     2、fulfilled(成功)

     3、reject(拒絕)

其中pending為初始狀態(tài),fulfilledrejected為結束狀態(tài)(結束狀態(tài)表示promise的生命周期已結束)。

狀態(tài)轉換關系為:

pending->fulfilled,pending->rejected。

隨著狀態(tài)的轉換將觸發(fā)各種事件(如執(zhí)行成功事件、執(zhí)行失敗事件等)。

Promise形式

Promise的長相就像這樣子:

var promise = new Promise(function func(resolve, reject){
 // do somthing, maybe async
 if (success){
 return resolve(data);
 } else {
 return reject(data);
 }
});

promise.then(function(data){
 // do something... e.g
 console.log(data);
}, function(err){
 // deal the err.
})

這里的變量promise是Promise這個對象的實例。

promise對象在創(chuàng)建的時候會執(zhí)行func函數(shù)中的邏輯。

邏輯處理完畢并且沒有錯誤時,resolve這個回調會將值傳遞到一個特殊的地方。這個特殊的地方在哪呢?就是下面代碼中的then,我們使用then中的回調函數(shù)來處理resolve后的結果。比如上面的代碼中,我們將值簡單的輸出到控制臺。如果有錯誤,則rejectthen的第二個回調函數(shù)中,對錯誤進行處理。

配合上面的有限狀態(tài)機的理論,我們知道在Promise構造函數(shù)中執(zhí)行回調函數(shù)代碼時,狀態(tài)為pendingresolve之后狀態(tài)為fulfilled,reject之后狀態(tài)為reject

Promise數(shù)據(jù)流動

以上是promise的第一次數(shù)據(jù)流動情況。

比較funny的是,promise的then方法依然能夠返回一個Promise對象,這樣我們就又能用下一個then來做一樣的處理。

第一個then中的兩個回調函數(shù)決定第一個then返回的是一個什么樣的Promise對象。

假設第一個then的第一個回調沒有返回一個Promise對象,那么第二個then的調用者還是原來的Promise對象,只不過其resolve的值變成了第一個then中第一個回調函數(shù)的返回值。

假設第一個then的第一個回調函數(shù)返回了一個Promise對象,那么第二個then的調用者變成了這個新的Promise對象,第二個then等待這個新的Promise對象resolve或者reject之后執(zhí)行回調。

話雖然饒了一點,但是我自我感覺說的還是很清楚的呢。哈哈~

如果任意地方遇到了錯誤,則錯誤之后交給遇到的第一個帶第二個回調函數(shù)的then的第二個回調函數(shù)來處理??梢岳斫鉃殄e誤一直向后reject, 直到被處理為止。

另外,Promise對象還有一個方法catch,這個方法接受一個回調函數(shù)來處理錯誤。

即:

promise.catch(function(err){
 // deal the err.
})

假設對錯誤的處理是相似的,這個方法可以對錯誤進行集中統(tǒng)一處理。所以其他的then方法就不需要第二個回調啦~

控制并發(fā)的Promise

Promise有一個"靜態(tài)方法"——Promise.all(注意并非是promise.prototype), 這個方法接受一個元素是Promise對象的數(shù)組。

這個方法也返回一個Promise對象,如果數(shù)組中所有的Promise對象都resolve了,那么這些resolve的值將作為一個數(shù)組作為Promise.all這個方法的返回值的(Promise對象)的resolve值,之后可以被then方法處理。如果數(shù)組中任意的Promise被reject,那么該reject的值就是Promise.all方法的返回值的reject值.

很op的一點是:

then方法的第一個回調函數(shù)接收的resolve值(如上所述,是一個數(shù)組)的順序和Promise.all中參數(shù)數(shù)組的順序一致,而不是按時間順序排序。

還有一個和Promise.all相類似的方法Promise.race,它同樣接收一個數(shù)組,只不過它只接受第一個被resolve的值。

將其他對象變?yōu)镻romise對象

Promise.resovle方法,可以將不是Promise對象作為參數(shù),返回一個Promise對象。

有兩種情形:

假設傳入的參數(shù)沒有一個.then方法,那么這個返回的Promise對象變成了resolve狀態(tài),其resolve的值就是這個對象本身。

假設傳入的參數(shù)帶有一個then方法(稱為thenable對象), 那么將這個對象的類型變?yōu)镻romise,其then方法變成Promise.prototype.then方法。

Promise是解決異步的方案嗎?

最后說一點很重要的事:Promise的作用是解決回調金字塔的問題,對于控制異步流程實際上沒有起到很大的作用。真正使用Promise對異步流程進行控制,我們還要借助ES6 generator函數(shù)。(例如Tj大神的co庫的實現(xiàn))。

然而ES7將有一個更加牛逼的解決方案:async/await,這個方案類似于co,但是加了原生支持。拭目以待吧。

總結

以上就是關于Javascript ES6中原生Promise的全部內容了,希望本文的內容對大家學習ES6能有所幫助。如果有疑問可以留言交流。

相關文章

  • 關于前端要知道的?AST知識

    關于前端要知道的?AST知識

    這篇文章主要介紹了關于前端要知道的?AST知識,在計算機科學中,抽象語法樹是源代碼語法結構的一種抽象表示,需要的朋友可以參考下
    2023-04-04
  • 關于JSON的定義以及如何使用

    關于JSON的定義以及如何使用

    這篇文章主要介紹了關于JSON的定義以及如何使用,JSON 的名稱中雖然帶有JavaScript,但這是指其語法規(guī)則是參考JavaScript對象的,而不是指只能用于JavaScript語言,需要的朋友可以參考下
    2023-07-07
  • javaScript語法總結

    javaScript語法總結

    本篇文章主要是對javascript語法進行總結,相信對大家的學習和復習都會有所幫助,需要的朋友可以過來看一下
    2016-11-11
  • js parsefloat parseint 轉換函數(shù)

    js parsefloat parseint 轉換函數(shù)

    JavaScript提供了3個顯式的類型轉換函數(shù),分別是eval()、parseInt()和parseFloat()。
    2010-01-01
  • JavaScript面向對象之class繼承類案例講解

    JavaScript面向對象之class繼承類案例講解

    這篇文章主要介紹了JavaScript面向對象之class繼承類案例講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • ajax跨域訪問遇到的問題及解決方案

    ajax跨域訪問遇到的問題及解決方案

    在本文中我們給大家整理了關于ajax跨域訪問的相關知識點以及遇到的問題和解決方法,需要的朋友們參考下。
    2019-05-05
  • 深入理解JavaScript中的語法和代碼結構

    深入理解JavaScript中的語法和代碼結構

    這篇文章主要介紹了JavaScript中的語法和代碼結構,對JS初學者而言,這些基礎一定要看一下
    2021-05-05
  • JavaScript中getUTCMinutes()方法的使用詳解

    JavaScript中getUTCMinutes()方法的使用詳解

    這篇文章主要介紹了JavaScript中getUTCMinutes()方法的使用詳解,是JS入門學習中的基礎知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript中的anchor()方法使用詳解

    JavaScript中的anchor()方法使用詳解

    這篇文章主要介紹了JavaScript中的anchor()方法使用,是JS入門學習中的基礎知識,需要的朋友可以參考下
    2015-06-06
  • 簡述JavaScript中正則表達式的使用方法

    簡述JavaScript中正則表達式的使用方法

    這篇文章主要介紹了JavaScript中正則表達式的使用方法,正則表達式是JS進階學習中的重要知識,本文簡述了JS對正則表達式的支持情況,需要的朋友可以參考下
    2015-06-06

最新評論

景德镇市| 龙海市| 尉氏县| 洪江市| 客服| 巴林左旗| 日喀则市| 玛纳斯县| 丽水市| 泰宁县| 广水市| 阳新县| 应城市| 松溪县| 渝北区| 东丰县| 叶城县| 石城县| 称多县| 明光市| 葫芦岛市| 德保县| 永春县| 永嘉县| 如东县| 喀喇沁旗| 婺源县| 娱乐| 扬州市| 友谊县| 府谷县| 呼和浩特市| 游戏| 贺兰县| 克东县| 武陟县| 濮阳县| 阿鲁科尔沁旗| 遵义市| 鄂温| 长垣县|