自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用 Promises 編寫更好的 JavaScript 代碼

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

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

Promises易于閱讀

比如說我們想從HipsterJesus的API中抓取一些數(shù)據(jù)并將這些數(shù)據(jù)添加到我們的頁面中。這些API的響應(yīng)數(shù)據(jù)形式如下:

  1. {  
  2.   "text""<p>Lorem ipsum...</p>",  
  3.   "params": {  
  4.     "paras": 4,  
  5.     "type""hipster-latin" 
  6.   }}  

要使用回調(diào)的話,我們通常要寫如下形式的東西:

  1. $.getJSON('http://hipsterjesus.com/api/'function(data) {  
  2.   $('body').append(data.text);  
  3. });  

如果你有jQuery的使用經(jīng)歷,你會(huì)認(rèn)出我們創(chuàng)建了一個(gè)GET請(qǐng)求并且希望響應(yīng)內(nèi)容是JSON。我們還傳遞了一個(gè)回調(diào)函數(shù)來接受響應(yīng)的JSON,以將數(shù)據(jù)添加到文檔中。

另外一種書寫方法是使用getJSON方法返回的promise對(duì)象。你可以直接在這個(gè)返回對(duì)象上綁定一個(gè)回調(diào)。

  1. var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) {  
  2.   $('body').append(data.text);  
  3. });  

在上面的回調(diào)例子中,當(dāng)響應(yīng)成功時(shí)它將API請(qǐng)求的結(jié)果添加到文檔中。但當(dāng)響應(yīng)失敗是會(huì)發(fā)生什么呢?我們可以在我們的promise上綁定一個(gè)失敗處理器。

  1. var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) {  
  2.   $('body').append(data.text);});promise.fail(function() {  
  3.   $('body').append('<p>Oh no, something went wrong!</p>');  
  4. });  

大多數(shù)人刪掉了promise變量,這樣更簡潔,一眼就能看出代碼的作用。

  1. $.getJSON('http://hipsterjesus.com/api/').done(function(data) {  
  2.   $('body').append(data.text);}).fail(function() {  
  3.   $('body').append('<p>Oh no, something went wrong!</p>');  
  4. });  

jQuery也包含一個(gè)一直發(fā)生的事件處理器,不論請(qǐng)求成功失敗都會(huì)被調(diào)用。

  1. $.getJSON('http://hipsterjesus.com/api/').done(function(data) {  
  2.   $('body').append(data.text);}).fail(function() {  
  3.   $('body').append('<p>Oh no, something went wrong!</p>');}).always(function() {  
  4.   $('body').append('<p>I promise this will always be added!.</p>');  
  5. });  

通過使用promise,回調(diào)的順序是按預(yù)期的。我們能確保正常回調(diào)先被調(diào)用,然后是失敗回調(diào),***是一直發(fā)生的回調(diào)。

更好的API

比如說我們想創(chuàng)造一個(gè)HipsterJesus API的封裝對(duì)象。我們會(huì)添加一個(gè)方法——html,它將來自API的HTML數(shù)據(jù)返回。與之前設(shè)置一個(gè)回調(diào)處理器來解析請(qǐng)求不同,我們可以讓方法返回一個(gè)promise對(duì)象。

  1. var hipsterJesus = {  
  2.   html: function() {  
  3.     return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {  
  4.       return data.text;  
  5.     });  
  6.   }};  

這個(gè)做法很酷,這樣我們可以繞過promise對(duì)象而不必?fù)?dān)心何時(shí)或如何解析它的值。任何需要promise返回值的代碼只需注冊(cè)一個(gè)成功響應(yīng)回調(diào)即可。

then方法允許我們修改promise的結(jié)果并將其傳遞給鏈中的下一個(gè)處理器。這意味現(xiàn)在我們可以這樣使用新的API:

  1. hipsterJesus.html().done(function(html) {  
  2.   $("body").append(html);  
  3. });  

直到最近,AngularJS出現(xiàn)了一個(gè)殺手級(jí)特性,模板可以直接綁定到promise。在Angular的控制器中,像這樣:

  1. $scope.hipsterIpsum = $http.get('http://hipsterjesus.com/api/');  

這樣,在模板中寫{{ hipsterIpsum.text }}就很簡單了。當(dāng)promise解析后,Angular不需要自動(dòng)更新視圖。不幸的是Angular團(tuán)隊(duì)已經(jīng)放棄了這一特性?,F(xiàn)在,它可以通過調(diào)用$parseProvider.unwrapPromises(true)來啟用。我希望Angular已經(jīng)其他框架一直包含此特性(我會(huì)一直留意)。

promise最出彩的部分是你可以將它們串聯(lián)起來。比如說我們想添加一個(gè)方法到一個(gè)返回一段數(shù)組的API。

  1. var hipsterJesus = {  
  2.  
  3.   html: function() {  
  4.     return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {  
  5.       return data.text;  
  6.     });  
  7.   },  
  8.  
  9.   paragraphs: function() {  
  10.     return this.html().then(function(html) {  
  11.       return html.replace(/<[^>]+>/g, "").split("");  
  12.     });  
  13.   }};  

我們以上面的方式這種HTML方法,我們用它在paragraphs方法中。因?yàn)閜romise回調(diào)函數(shù)的返回值將傳遞給鏈中的下一個(gè)回調(diào),我們能夠在通過它們時(shí)自由地創(chuàng)建小的、功能性的方法來改變數(shù)據(jù)。

我們可以按需求任意次串聯(lián)promise。讓我們添加一個(gè)。

  1. var hipsterJesus = {  
  2.  
  3.   html: function() {  
  4.     return $.getJSON('http://hipsterjesus.com/api/').then(function(data) {  
  5.       return data.text;  
  6.     });  
  7.   },  
  8.  
  9.   paragraphs: function() {  
  10.     return this.html().then(function(html) {  
  11.       return html.replace(/<[^>]+>/g, "").split("");  
  12.     });  
  13.   },  
  14.  
  15.   sentences: function() {  
  16.     return this.paragraphs().then(function(paragraphs) {  
  17.       return [].concat.apply([], paragraphs.map(function(paragraph) {  
  18.         return paragraph.split(/. /);  
  19.       }));  
  20.     });  
  21.   }};  

多個(gè)調(diào)用
 

可能promise最顯著的特點(diǎn)是調(diào)用多個(gè)API的能力。當(dāng)使用回調(diào)時(shí),如果你需要同時(shí)創(chuàng)建兩個(gè)API調(diào)用時(shí)會(huì)發(fā)生什么呢?你可能會(huì)這樣寫:

  1. var firstData = null;var secondData = null;var responseCallback = function() {  
  2.  
  3.   if (!firstData || !secondData)  
  4.     return;  
  5.  
  6.   // do something}$.get("http://example.com/first", function(data) {  
  7.   firstData = data;  
  8.   responseCallback();});$.get("http://example.com/second"function(data) {  
  9.   secondData = data;  
  10.   responseCallback();  
  11. });  

使用promise的話,這就簡單多了:

  1. var firstPromise = $.get("http://example.com/first");  
  2. var secondPromise = $.get("http://example.com/second");  
  3. $.when(firstPromise, secondPromise).done(function(firstData, secondData) {  
  4.   // do something  
  5. });  

這里我們使用when方法,將其綁定到一個(gè)供兩個(gè)請(qǐng)求都完成時(shí)調(diào)用的處理器上。

結(jié)論

這就是promise。希望你馬上就想到一些可以用promise實(shí)現(xiàn)的的可怕的事情。你最喜歡使用它們的方式是什么?在評(píng)論中告訴我吧!

*注:為簡單起見,本文使用了jQuery的延期執(zhí)行。jQuery的Deferred對(duì)象Promises/A+的規(guī)范間有細(xì)微的差別,這個(gè)規(guī)范更標(biāo)準(zhǔn)。更多信息,查看jQuery維基上的問答。

英文原文:Write Better JavaScript with Promises

譯文鏈接:http://www.oschina.net/translate/write-javascript-promises

責(zé)任編輯:林師授 來源: 中國開源社區(qū) 編譯
相關(guān)推薦

2021-06-09 10:45:12

JavaScript開發(fā) 編程

2023-10-10 08:00:00

2021-03-17 08:00:59

JS語言Javascript

2024-10-22 15:10:49

2020-05-08 19:52:31

Reactreact.js前端

2016-11-30 18:35:03

JavaScript

2012-12-17 13:51:22

Web前端JavaScriptJS

2022-06-07 09:30:35

JavaScript變量名參數(shù)

2019-06-27 10:35:40

JavaScript條件式匹配條件

2020-06-15 11:04:38

JavaScript 代碼JavaScript

2013-04-15 09:02:43

JavaScriptJS

2020-06-23 07:50:13

Python開發(fā)技術(shù)

2009-06-24 15:00:39

Javascript代

2020-10-04 13:15:37

代碼技術(shù)開發(fā)

2020-06-23 07:48:18

Python開發(fā)技術(shù)

2022-06-21 09:26:21

Shell腳本JavaScript

2023-10-30 23:25:48

FuturesGo語言

2011-03-04 10:11:09

JavascriptAPI

2014-12-01 09:54:40

JavaScript

2020-08-06 00:25:38

Python代碼開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)