初識JavaScript Promises

來源:互聯網
上載者:User

JavaScript有很多槽點,嵌套回調怕是千夫所指。 很久之前,我一直使用async來處理JavaScript非同步編程中的嵌套回調問題。當然我也大概的瞭解過一些其它旨在解決這些問題的類庫,諸如EventProxy、Jscex、StepJS、thenjs。 當我第一次看到Promises規範的時候,我根本無法理解它所帶來的好處。譬如每個初次學習Promises的人都見過如下的範例程式碼: //callbacks     function callback(err, value){<br>        if(err){<br>            // do something<br>            return;<br>        }<br>        //do other things     with value     }     //Promises     promise.then(function(value){<br>        //do something with value     }, function(err){<br>        //do other things with error      })很難相信上面的代碼會讓人對Promises刮目相看。不過正如bluebird作者Petka所說,上面的代碼是 “最不誠實的比較”。所以我懇請你把類似的代碼從你的記憶中擦出吧。 不妨讓我們再回到async的討論上。async的問題在於它不能優雅地應對需求的變化,一旦商務邏輯有較大的變化,代碼結構會進行大幅度的調整,而Promises卻能夠輕鬆的應對這種變化。待時機適宜我會進行詳細的比較,首先讓我們開始快速地瞭解Promises。 Promises是什麼Promises象徵著一個非同步作業的最終結果。Promises互動主要通過它的then方法,then方法接受一個回呼函數,這個回呼函數接受執行成功的傳回值或執行失敗的錯誤原因,錯誤原因一般是Error對象。需要注意的是,then方法執行的傳回值是一個Promise對象,而then方法接受的回呼函數的傳回值則可以是任意的JavaScript對象,包括Promises。基於這種機制,Promise對象的鏈式調用就起作用了。 Promises的狀態Promise對象有三種狀態:pending(初始狀態)、fulfilled(成功執行)、rejected(執行出錯)。pending狀態的Promise對象可以轉換到其它兩種狀態。 上面的文本不夠形象,不妨上些代碼來加深對Promises的認識。 註:由於主流的JavaScript環境(包括NodeJS)對Promises/A+標準的實現不太令人滿意,我的樣本均使用了第三方類庫bluebird。  var fs = require('fs')var Promise = require('bluebird')//改造fs.readFile為Promise版本    var readFileAsync = function(path){        //返回一個Promise對象,初始狀態pending        return new Promise(function(fulfill, reject){        fs.readFile(path,  'utf8', function(err, content){            //由pending狀態進入rejected狀態            if(err)return reject(err)            //由pending狀態進入fulfilled狀態            return fulfill(content)        })    })    }    //開始使用,調用其then方法,回調接受執行成功的傳回值    readFileAsync('./promise-1.js').then(function(content){    console.log(content)    })看了上面的代碼以後,是不是覺得Promises其實並不複雜呢。 OK,我們繼續延續上面的代碼,來簡單比較一下傳統回調和Promises的使用上的差別:  /** 簡單比較一下傳統方式和Promises方式* 需求:讀取兩個檔案並列印內容* */     //callbacks    fs.readFile('./promise-1.js', 'utf8', function(err, content1){        //嵌套一次        console.log('#', content1)        fs.readFile('./promise-1.js', 'utf8', function(err, content2){            //第二次嵌套            console.log('##', content2)        })    })    //Promises    readFileAsync('./promise-1.js').then(function(content1){        console.log('#', content1)        //這裡返回一個Promise對象        return readFileAsync('./promiscuitye-1.js')    }).then(function(content2){        console.log('##', content2)    })上面的代碼都沒有錯誤處理,這是一個後果很嚴重的壞習慣。不過今天我們的重點不在這裡,而是分析上下兩段代碼的主要區別。 第一段代碼是傳統的嵌套回調,在第二次列印的時候已經使用了兩次縮排,而Promises鏈式調用then方法成功地避免了一次縮排(嵌套),維持了代碼結構的相對平坦。上面的代碼略顯簡陋,如果再加上錯誤處理,Promises毫無疑問將會大放光彩,有興趣請關注後續章節。 本章寫到這裡就結束了,相信大家已經對Promises的有了一個初步認識。規範文檔往往很難理解,我沒有過多的描述規範,因為我相信代碼最能夠解釋一切。不過對規範文檔有興趣的可以自行閱讀參考連結。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.