溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

javascript Promise是什么

發(fā)布時(shí)間:2021-11-17 15:04:58 來(lái)源:億速云 閱讀:118 作者:iii 欄目:web開(kāi)發(fā)

這篇文章主要介紹“javascript Promise是什么”,在日常操作中,相信很多人在javascript Promise是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”javascript Promise是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

什么是Promise

Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6將其寫(xiě)進(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)入門(mén)一書(shū)。S6標(biāo)準(zhǔn)入門(mén)。多說(shuō)一句,目前的JavaScript項(xiàng)目無(wú)論是前臺(tái)或者是后臺(tái),都應(yīng)該采用ES6的標(biāo)準(zhǔn)語(yǔ)法來(lái)寫(xiě),ES6讓JavaScript的書(shū)寫(xiě)更加的清晰和規(guī)范。

基本用法

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

var promise = new Promise(function(resolve, reject) {   // ... here is some code    if (/* 異步操作成功 */){     resolve(value);   } else {     reject(error);   } });

上面的例子給出了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ù)。例如這樣

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ù),然后寫(xiě)到一個(gè)db里,或者一個(gè)存儲(chǔ)里,***在把存儲(chǔ)的狀態(tài)龍出來(lái),那么如果沒(méi)有promise是怎么寫(xiě)的呢?可能會(huì)是這樣。

getData(function (value1) {   storeToDb(value1, function(value2) {     logStore(value2, function(value3) {       //...     });   }); });

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

function getData(){     return new Promise((resolve,reject) =>{         // ... send request to get data                  if(/* get successfully*/){             resolve(data)         }else{             reject(err)         }     }) }  function storeData(data){     return new Promise((resolve,reject)=>{         // ... store the data                  if(/*store successfully*/){             resolve(data)         }else{             reject(err)         }     }) }   getData()     .then(data => storeData(data))     .then(data => console.log('the process is done',data));     .catch(err => console.error('there is the err',err));

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

def get_data      // ...send request          if /*get successfully */         return data     else         raise GetDataError     end end   def store_data     // ...save to db          if /*save successfully */         return data     else         raise StoreDataError     end end   /*Main Logic*/ begin     request_data = get_data     db_data = store_data request_data     p "here is the store data #{db_data}" rescue e     p "here is some errors #{e}" end

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

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

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

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

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è)例子:

var guid = 0; function run() {   guid++;   var id = guid;   return new Promise(resolve => {     setTimeout(function () {       console.log(id);       resolve(id);     }, (Math.random() * 1.5 | 0) * 1000);   }); }  var promises = Array.from({ length: 10 }, run); Promise.all(promises)

OUTPUT:

2 3 5 6 7 8 10 1 4 9

到此,關(guān)于“javascript Promise是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI