JavaScript中的Promise機制

JavaScript中的Promise機制。

1.前言:

如我們所知道的javascript是一門單線程語言,不像java語言中有多線程的機制,前不久做項目的時候,需要在前端使用js進行一些列的ajax異步請求,這些請求之間有一種關系,就是下一次請求的參數是上一次請求的結果,在javaweb端我們可以很容易的用同步請求的方式解決,阻塞線程知道函數執行完,但是在前端的ajax中就得不斷的嵌套函數,十分的惡心,好在最後找到瞭Promise這個好東西,並將學習成果總結下來。

2.Promise:

2.1:Promise 的resolve 和reject

就如其名一樣,Promise類似於某種承諾,當我們在特定的時候告訴它應該幹什麼(異步請求成功後),它就會在接受到結果後第一時間告訴我們,類似於java中的回調函數,而且它可以使用一種鏈式的結構,將我們的異步請求連接起來,隻有當我們前面的異步請求成功後,後面的異步函數才會執行。

舉個栗子:

這裡寫圖片描述

這裡我們簡單的模擬瞭一個異步請求,在兩秒後我們可以看到alert顯示瞭我們的信息,這看起來貌似沒有什麼蛋用啊,可是這隻是一個簡單的演示,如果我們的異步請求多瞭就可以看出它的威力瞭,解析來我們就來一個三個異步的栗子:

這裡寫圖片描述

上面的代碼看起來有點亂啊,其實就是三個延遲函數而已,我們可以在控制臺上看見間隔2秒、1秒、1秒後我們的結果按順序的打印出來瞭,實際情況中我們並不會這樣寫,這樣多來幾次有懵逼瞭,我們最終的代碼會像如下這樣:

第一個異步請求的: promise.then(function(result){

return promise2;

}).then(function(result2){

reutrn promise3;

})…//N個一條鏈式的結構

那這就有一個疑問瞭,網絡請求不都是成功的,可能是失敗的,我們不希望在請求失敗後依然去調用下一個請求,這是我們就需要Promise函數的第二個方法瞭,Promise.reject();用法和第一個成功回調一樣,唯一的區別是回調的函數有一點差異,下面就舉一個栗子:

這裡寫圖片描述

這裡我們定義瞭一個假的異步請求,我們隨機一個返回值,如果大於5,我們就認為成功,alert success回調,如果失敗就在控制臺打印。大傢就發現瞭,then()函數的第二個參數就是失敗的回調,一個promise要麼成功要麼失敗。

以上就是Promise的簡單使用,我們再來看幾個高級一點的例子:

假設有如下場景,我們查詢兩種分開的表,前一張表的結果是後一張表的參數,而且後一次查詢還不止一次,打個比方:我們去買蘋果,買蘋果就是我們的第一個請求,但是有很多種的蘋果,我們為瞭確定哪個好吃我們需要每種都試吃一遍,然後選擇一種,當然如果在現實中,可能我們這樣做草都一米高瞭。這時候前面的方法就不適用瞭,我們需要一個新的方法。

2.2 Promise的all:

Promise.all()函數就是一個解決上訴問題的方法,它接受一個promise的數組,當這些promise都執行完後或則有一個失敗的時候回調。

這裡寫圖片描述

我們定義兩個成功的回調,在兩個異步執行完成之後,我們會得到一個保存結果的數組,結果數組中的結果與之前的參數的promise對應,就是p3的結果是result[0],依次類推。

那麼在如果我們的異步請求中如果有一個出錯的會怎麼樣瞭?

這裡寫圖片描述

我們將上訴方法稍微改造下,讓第二個異步失敗,此時我們可以在控制臺上輸出瞭four error,並沒有three的影子,這就是all的特點,要麼全部成功,要麼在第一個error出停止。我們接著看下一個函數。

2.3 Promise的race:

這個方法比較有意思,Promise.race(),這個方法也是接受一個promise數組作為參數,返回一個promise,但是它就如它的名字一樣,他隻返回最先執行完的第一個promise的結果。

2.4Promise的catch:

在上面我們說瞭promise可以將一系列的異步請求串起來,此時就有一個問題,如果我們不想在每個異步請求的回調裡去檢測失敗,隻關心最終的結果,此時我們就可以使用catch()函數,它可以捕獲我們執行調用鏈中的reject和exception,寫法如下:

promise.then(function(){

return promise;

}).then(function(){

//do something

}).catch(function(error){

})

這裡需要註意的就是,當我們回調鏈中有一個函數接受瞭錯誤的回調,那麼catch函數就不會被調用瞭。以上就是javascript自帶的Promise,下面我們看一個Angular1.x中的Promise機制。

3.Angular中的$q

在Angular1.x中我們可以在controller中註入$q使用Promise函數下面就簡單介紹一下。

//聲明一個模塊

var app=angular.module('appM',[]);

//定義一個控制器並註入我們的$scope和$q

app.controller('myCtrl',['$scope','$q',function($scope,$q){

//定義一個異步請求方法:

$scope.httpRequest=function(param){

var defer=$q.defer();

//異步操作

if(suc){

defer.resolve();

}else{

defer.reject();

}

return defer.promise;

}

$scope.httpRequest().then(function(suc){

//成功

},function(er){

//失敗

})

}])

Angular中的$q還有

when():一般在參數不確定的時候使用 all():和javascript中的效果一樣 finally():類似於java中的try catch最後的finally方法。

發佈留言