新聞中心
你可能已經(jīng)無意中聽說過 Promises 是多么的代表未來。所有酷孩子們都使用它們,但你不知道為什么它們?nèi)绱颂貏e。難道你不能使用回調(diào)么?有什么了不起的?在本文中,我們將看看promises是什么以及如何使用它們寫出更好的JavaScript。

創(chuàng)新互聯(lián)公司是一家專業(yè)提供都江堰企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計、小程序制作等業(yè)務(wù)。10年已為都江堰眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。
Promises易于閱讀
比如說我們想從HipsterJesus的API中抓取一些數(shù)據(jù)并將這些數(shù)據(jù)添加到我們的頁面中。這些API的響應(yīng)數(shù)據(jù)形式如下:
- {
- "text": "
Lorem ipsum...
",- "params": {
- "paras": 4,
- "type": "hipster-latin"
- }}
要使用回調(diào)的話,我們通常要寫如下形式的東西:
- $.getJSON('http://hipsterjesus.com/api/', function(data) {
- $('body').append(data.text);
- });
如果你有jQuery的使用經(jīng)歷,你會認(rèn)出我們創(chuàng)建了一個GET請求并且希望響應(yīng)內(nèi)容是JSON。我們還傳遞了一個回調(diào)函數(shù)來接受響應(yīng)的JSON,以將數(shù)據(jù)添加到文檔中。
另外一種書寫方法是使用getJSON方法返回的promise對象。你可以直接在這個返回對象上綁定一個回調(diào)。
- var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) {
- $('body').append(data.text);
- });
在上面的回調(diào)例子中,當(dāng)響應(yīng)成功時它將API請求的結(jié)果添加到文檔中。但當(dāng)響應(yīng)失敗是會發(fā)生什么呢?我們可以在我們的promise上綁定一個失敗處理器。
- var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) {
- $('body').append(data.text);});promise.fail(function() {
- $('body').append('
Oh no, something went wrong!
');- });
大多數(shù)人刪掉了promise變量,這樣更簡潔,一眼就能看出代碼的作用。
- $.getJSON('http://hipsterjesus.com/api/').done(function(data) {
- $('body').append(data.text);}).fail(function() {
- $('body').append('
Oh no, something went wrong!
');- });
jQuery也包含一個一直發(fā)生的事件處理器,不論請求成功失敗都會被調(diào)用。
- $.getJSON('http://hipsterjesus.com/api/').done(function(data) {
- $('body').append(data.text);}).fail(function() {
- $('body').append('
Oh no, something went wrong!
');}).always(function() {- $('body').append('
I promise this will always be added!.
');- });
通過使用promise,回調(diào)的順序是按預(yù)期的。我們能確保正?;卣{(diào)先被調(diào)用,然后是失敗回調(diào),***是一直發(fā)生的回調(diào)。
更好的API
比如說我們想創(chuàng)造一個HipsterJesus API的封裝對象。我們會添加一個方法——html,它將來自API的HTML數(shù)據(jù)返回。與之前設(shè)置一個回調(diào)處理器來解析請求不同,我們可以讓方法返回一個promise對象。
- var hipsterJesus = {
- html: function() {
- return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {
- return data.text;
- });
- }};
這個做法很酷,這樣我們可以繞過promise對象而不必?fù)?dān)心何時或如何解析它的值。任何需要promise返回值的代碼只需注冊一個成功響應(yīng)回調(diào)即可。
then方法允許我們修改promise的結(jié)果并將其傳遞給鏈中的下一個處理器。這意味現(xiàn)在我們可以這樣使用新的API:
- hipsterJesus.html().done(function(html) {
- $("body").append(html);
- });
直到最近,AngularJS出現(xiàn)了一個殺手級特性,模板可以直接綁定到promise。在Angular的控制器中,像這樣:
- $scope.hipsterIpsum = $http.get('http://hipsterjesus.com/api/');
這樣,在模板中寫{{ hipsterIpsum.text }}就很簡單了。當(dāng)promise解析后,Angular不需要自動更新視圖。不幸的是Angular團隊已經(jīng)放棄了這一特性?,F(xiàn)在,它可以通過調(diào)用$parseProvider.unwrapPromises(true)來啟用。我希望Angular已經(jīng)其他框架一直包含此特性(我會一直留意)。
鏈
promise最出彩的部分是你可以將它們串聯(lián)起來。比如說我們想添加一個方法到一個返回一段數(shù)組的API。
- var hipsterJesus = {
- html: function() {
- return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {
- return data.text;
- });
- },
- paragraphs: function() {
- return this.html().then(function(html) {
- return html.replace(/<[^>]+>/g, "").split("");
- });
- }};
我們以上面的方式這種HTML方法,我們用它在paragraphs方法中。因為promise回調(diào)函數(shù)的返回值將傳遞給鏈中的下一個回調(diào),我們能夠在通過它們時自由地創(chuàng)建小的、功能性的方法來改變數(shù)據(jù)。
我們可以按需求任意次串聯(lián)promise。讓我們添加一個。
- var hipsterJesus = {
- html: function() {
- return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {
- return data.text;
- });
- },
- paragraphs: function() {
- return this.html().then(function(html) {
- return html.replace(/<[^>]+>/g, "").split("");
- });
- },
- sentences: function() {
- return this.paragraphs().then(function(paragraphs) {
- return [].concat.apply([], paragraphs.map(function(paragraph) {
- return paragraph.split(/. /);
- }));
- });
- }};
多個調(diào)用
可能promise最顯著的特點是調(diào)用多個API的能力。當(dāng)使用回調(diào)時,如果你需要同時創(chuàng)建兩個API調(diào)用時會發(fā)生什么呢?你可能會這樣寫:
- var firstData = null;var secondData = null;var responseCallback = function() {
- if (!firstData || !secondData)
- return;
- // do something}$.get("http://example.com/first", function(data) {
- firstData = data;
- responseCallback();});$.get("http://example.com/second", function(data) {
- secondData = data;
- responseCallback();
- });
使用promise的話,這就簡單多了:
- var firstPromise = $.get("http://example.com/first");
- var secondPromise = $.get("http://example.com/second");
- $.when(firstPromise, secondPromise).done(function(firstData, secondData) {
- // do something
- });
這里我們使用when方法,將其綁定到一個供兩個請求都完成時調(diào)用的處理器上。
結(jié)論
這就是promise。希望你馬上就想到一些可以用promise實現(xiàn)的的可怕的事情。你最喜歡使用它們的方式是什么?在評論中告訴我吧!
*注:為簡單起見,本文使用了jQuery的延期執(zhí)行。jQuery的Deferred對象和Promises/A+的規(guī)范間有細(xì)微的差別,這個規(guī)范更標(biāo)準(zhǔn)。更多信息,查看jQuery維基上的問答。
英文原文:Write Better JavaScript with Promises
譯文鏈接:http://www.oschina.net/translate/write-javascript-promises
分享名稱:使用Promises編寫更好的JavaScript代碼
當(dāng)前URL:http://www.dlmjj.cn/article/dhgdghj.html


咨詢
建站咨詢
