成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

只為那句承諾-大話Promise

開(kāi)發(fā) 前端
Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對(duì)象。所謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。

[[175061]]

大家周末好,要說(shuō)最近幾年什么語(yǔ)言大紅大紫,當(dāng)屬JavaScript了。話說(shuō)雖然是10天就創(chuàng)造出的語(yǔ)言,但是人家能文能武。web前端自然不必多說(shuō)了,各種框架你方登罷我上場(chǎng),前兩年還是Angular一統(tǒng)天下,這兩年React又是大紅大紫,還有Vue最近異軍突起,好不紅火。要是僅僅是前端也就算了,但是由于Node.js人家在后臺(tái)也能寫,React Native的出現(xiàn)讓人家移動(dòng)端也能做。好吧,還有硬件上也出現(xiàn)Ruff方案,好像硬件上也能寫了。真是讓人感覺(jué)挺有意思的事情。

圖表君上邊叨叨了這么多,難道是為JavaScript唱贊歌的嗎?呵呵,其實(shí)并不是。只是最近因?yàn)樵谟蒙掀恼陆榻B的AWS Lambda。Lambda現(xiàn)在只支持Java,Node.js,Python。最終選擇了Node.js進(jìn)行開(kāi)發(fā),不可避免的要牽扯到異步操作的問(wèn)題。那么今天就來(lái)聊聊JavaScript中的Promise。

什么是Promise

Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對(duì)象。

所謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō),Promise是一個(gè)對(duì)象,從它可以獲取異步操作的消息。Promise提供統(tǒng)一的API,各種異步操作都可以用同樣的方法進(jìn)行處理。

上面是Promise的一個(gè)定義,引自阮一峰的ES6標(biāo)準(zhǔn)入門一書。S6標(biāo)準(zhǔn)入門。多說(shuō)一句,目前的JavaScript項(xiàng)目無(wú)論是前臺(tái)或者是后臺(tái),都應(yīng)該采用ES6的標(biāo)準(zhǔn)語(yǔ)法來(lái)寫,ES6讓JavaScript的書寫更加的清晰和規(guī)范。

基本用法

如何來(lái)構(gòu)造一個(gè)promise對(duì)象呢?ES6中提供了原生Promise可以使用。

  1. var promise = new Promise(function(resolve, reject) { 
  2.   // ... here is some code 
  3.  
  4.   if (/* 異步操作成功 */){ 
  5.     resolve(value); 
  6.   } else { 
  7.     reject(error); 
  8.   } 
  9. });  

上面的例子給出了new一個(gè)promise對(duì)象的方法,Promise的構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)傳入,這個(gè)函數(shù)的兩個(gè)參數(shù),reject和resolve是JavaScript本身提供的兩個(gè)函數(shù)。一個(gè)promise對(duì)象有三個(gè)狀態(tài)分別是,pending,resolved,rejected。resolve函數(shù)可以將pending狀態(tài)轉(zhuǎn)變?yōu)閞esolved狀態(tài)。reject函數(shù)可以講pending狀態(tài)轉(zhuǎn)變了rejected狀態(tài)。對(duì)象的狀態(tài)不受外界的影響,同樣也是promise名字的由來(lái)。外部你拿著我的一個(gè)承諾,一會(huì)我會(huì)告訴你我的狀態(tài)。

promise對(duì)象通過(guò)then方法來(lái)添加回調(diào)函數(shù)。例如這樣

  1. promise.then(data=> console.log(data), err=> console.log(err)); 

當(dāng)promise被resolved的時(shí)候,就會(huì)把data log出來(lái)。當(dāng)promise被rejected的時(shí)候,err就會(huì)被log出來(lái)??瓷先ズ孟袷峭?jiǎn)單的,的確Promise的應(yīng)用使得異步的操作,以同步的形式表現(xiàn)出來(lái)。當(dāng)發(fā)生錯(cuò)誤的時(shí)候可以通過(guò)catch方法,來(lái)定義回調(diào)函數(shù)。

怎么用

上邊都是一些干巴巴的定義,那么到底該怎么用呢?Promise又怎么樣的解決了問(wèn)題呢,下邊我們看一個(gè)例子。假設(shè)下邊一個(gè)場(chǎng)景,我們一個(gè)服務(wù),從一個(gè)外邊service獲取數(shù)據(jù),然后寫到一個(gè)db里,或者一個(gè)存儲(chǔ)里,***在把存儲(chǔ)的狀態(tài)龍出來(lái),那么如果沒(méi)有promise是怎么寫的呢?可能會(huì)是這樣。 

  1. getData(function (value1) { 
  2.   storeToDb(value1, function(value2) { 
  3.     logStore(value2, function(value3) { 
  4.       //... 
  5.     }); 
  6.   }); 
  7. });  

傳統(tǒng)的回調(diào)的寫法,這樣使得代碼邏輯混亂在一起。再想想如果再加上錯(cuò)誤處理的情況,更是酸爽。那么用promise來(lái)寫會(huì)怎么樣呢?看下邊這樣的代碼

  1. function getData(){ 
  2.     return new Promise((resolve,reject) =>{ 
  3.         // ... send request to get data 
  4.          
  5.         if(/* get successfully*/){ 
  6.             resolve(data) 
  7.         }else
  8.             reject(err) 
  9.         } 
  10.     }) 
  11.  
  12. function storeData(data){ 
  13.     return new Promise((resolve,reject)=>{ 
  14.         // ... store the data 
  15.          
  16.         if(/*store successfully*/){ 
  17.             resolve(data) 
  18.         }else
  19.             reject(err) 
  20.         } 
  21.     }) 
  22.  
  23.  
  24. getData() 
  25.     .then(data => storeData(data)) 
  26.     .then(data => console.log('the process is done',data)); 
  27.     .catch(err => console.error('there is the err',err));  

這樣寫是不是就是很清楚了,先getData,然后再storeData,***將這次運(yùn)行的情況log了出來(lái),其中有任何的問(wèn)題,在catch中都可以Catch出來(lái)。代碼的邏輯以同步的方式得到了體現(xiàn)。我們來(lái)看看如果是其他語(yǔ)言會(huì)怎么寫,下邊是個(gè)ruby的語(yǔ)言的例子 

  1. def get_data  
  2.     // ...send request 
  3.      
  4.     if /*get successfully */ 
  5.         return data 
  6.     else 
  7.         raise GetDataError 
  8.     end 
  9. end 
  10.  
  11.  
  12. def store_data 
  13.     // ...save to db 
  14.      
  15.     if /*save successfully */ 
  16.         return data 
  17.     else 
  18.         raise StoreDataError 
  19.     end 
  20. end 
  21.  
  22.  
  23. /*Main Logic*/ 
  24. begin 
  25.     request_data = get_data 
  26.     db_data = store_data request_data 
  27.     p "here is the store data #{db_data}" 
  28. rescue e 
  29.     p "here is some errors #{e}" 
  30. end  

我們對(duì)比兩個(gè)例子,可以看到在使用的Promise后讓JavaScript的異步方式的編程模式更將清楚,也更加讓人容易理解。

由于JavaScript的執(zhí)行環(huán)境是單線程的,所以大量采用了異步的方式來(lái)進(jìn)行編程,這使得我們寫起代碼并不十分符合我們一般的習(xí)慣。但是Promise的出現(xiàn)讓這種問(wèn)題能得到一定程度的緩解。

但是異步操作異步操作的好處,比如上邊的那個(gè)例子,如果我們想要做的同時(shí)并發(fā)10個(gè)操作,那個(gè)在ruby或者其他語(yǔ)言中中就要啟多個(gè)線程來(lái)進(jìn)行。但是JavaScript就完全沒(méi)有這個(gè)問(wèn)題。只要簡(jiǎn)單的loop下就行了。

但是如果我們想要在這10個(gè)操作完成后根據(jù)返回的狀態(tài)做點(diǎn)其他操作該怎么做呢?這時(shí)候用Promise.all就是***的了。

  1. let p = Promise.all([p1, p2, p3]); 

Promise.all接受數(shù)組作為參數(shù)傳入,每個(gè)元素都是一個(gè)promise對(duì)象。只要所有子promise都resolved以后,p才會(huì)被resolved。只要有一個(gè)被rejected,這個(gè)p就會(huì)被rejected。但是有一點(diǎn)是這些子promise之間并不會(huì)有順序的關(guān)系。再來(lái)看一個(gè)例子:

  1. var guid = 0; 
  2. function run() { 
  3.   guid++; 
  4.   var id = guid; 
  5.   return new Promise(resolve => { 
  6.     setTimeout(function () { 
  7.       console.log(id); 
  8.       resolve(id); 
  9.     }, (Math.random() * 1.5 | 0) * 1000); 
  10.   }); 
  11.  
  12. var promises = Array.from({ length: 10 }, run); 
  13. Promise.all(promises)  

OUTPUT:

  1. 10 
  2.  

從這次的output可以看到,promise之間并沒(méi)有順序執(zhí)行,實(shí)際上是并發(fā)的。那么如何讓這些promise是順序執(zhí)行呢?留個(gè)大家自己思考下,下篇文章,我們揭曉。或者可以聯(lián)系圖表君,私下告訴你答案哦。 ps,當(dāng)然也可以用一些第三方的庫(kù)和方案,例如(async)來(lái)實(shí)現(xiàn)順序操作,但是代碼的樂(lè)趣不就是做些思維挑戰(zhàn)嗎:)

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2018-04-09 08:17:36

線程ThreadLocal數(shù)據(jù)

2022-09-12 06:35:00

C++協(xié)程協(xié)程狀態(tài)

2023-09-15 15:31:23

異步編程Promise

2022-08-08 10:45:49

PromiseJava腳手架

2025-02-07 12:09:37

2009-06-02 16:58:56

運(yùn)維管理配置摩卡

2011-12-02 08:51:19

PHP

2017-02-14 08:36:56

2020-12-15 08:01:24

Promise參數(shù)ES6

2020-07-29 17:35:08

Promise源碼前端

2016-08-24 11:13:30

2016-07-07 11:37:04

災(zāi)備

2009-10-26 15:18:39

HTML 5

2012-09-10 15:57:58

云計(jì)算混合云私有云

2010-07-06 08:56:54

JBoss ToolsEclipse 3.6

2015-02-10 17:21:20

2023-07-24 00:14:14

OpenAI人工智能微軟

2021-09-16 17:32:28

思科碳中和

2020-04-21 15:31:00

云安全云計(jì)算基礎(chǔ)設(shè)施

2013-04-28 10:05:17

亞馬遜Web服務(wù)AWSAWS價(jià)格
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 精品国产一区二区三区久久久久久 | 七七婷婷婷婷精品国产 | 精品国产一区二区三区久久 | 成人午夜视频在线观看 | 精品中文字幕久久 | 成人免费视屏 | 日韩高清不卡 | 成人精品久久 | 99在线观看 | 精品视频久久久 | 97视频精品 | 91偷拍精品一区二区三区 | 国产日韩欧美精品一区二区三区 | 91国内视频在线 | 国产精品99久 | 亚洲精品一区中文字幕乱码 | 亚洲激精日韩激精欧美精品 | 国产传媒毛片精品视频第一次 | 黑人精品欧美一区二区蜜桃 | 草草视频在线免费观看 | 这里精品 | 精品国产伦一区二区三区观看方式 | 91一区二区| 喷水毛片| 羞羞视频免费观看 | 亚洲激情综合网 | 成人在线电影网站 | 男人视频网站 | 国产精品一区二区日韩 | 亚洲精品视频在线观看视频 | 国产精品精品视频一区二区三区 | 国产精品精品视频一区二区三区 | 97在线播放 | 91av视频在线| 国产成人精品网站 | 国产99精品 | 欧美视频免费在线观看 | 中文字幕一区二区三区四区 | 欧美一区二区在线观看 | 在线天堂免费中文字幕视频 | 欧美日韩中文字幕在线 |