從C#到TypeScript-Promise-創新互聯

從C#到TypeScript - Promise

背景

相信之前用過JavaScript的朋友都碰到過異步回調地獄(callback hell),N多個回調的嵌套不僅讓代碼讀起來十分困難,維護起來也很不方便。
其實C#在Task出現之前也是有類似場景的,Async Programming Mode時代,用ActionFunc做回調也很流行,不過也是意識到太多的回調嵌套代碼可讀性差且維護不易,微軟引入了Task和Task-based Async Pattern。
雖然不知道是哪個語言最早有這個概念,但相信是C#把async await帶到流行語言的舞臺,接著其他語言也以不同的形式支持async await,如Python, Dart, Swift等。
JavaScript同樣在ES6開始支持PromiseGenerator,并在ES7中提出支持async await的議案。

成都創新互聯是一家專業提供蘭陵企業網站建設,專注與成都網站建設、網站制作、html5、小程序制作等業務。10年已為蘭陵眾多企業、政府機構等服務。創新互聯專業網絡公司優惠進行中。

這篇先來看看Promise:

Promise的特點

Promise之于TypeScript,相當于Task之于C#,只有返回Promise的函數才能使用async await
Promise其實就是一個可以獲取異步結果,并封裝了一些異步操作的對象。
有三個狀態:
pending: 進行中
resolved: 成功
rejected: 失敗
并且這三個狀態只有兩種轉換:pending->resolved、pending->rejected,不是成功就是失敗,并沒有多余的狀態轉換。
這兩種轉換都是由異步返回的結果給定的,成功取回數據就是resolved,取數據出異常就是rejected
也因此,這轉換過后的結果就是固定的了,不可能在轉換過后還會變回pending或其他狀態。
Promise不能在任務進行中取消,只能等結果返回,這點上不如C#的Task,Task可以通過CancelTaskToken來取消任務。

Promise的使用

可以直接new一個Promise對象,構造函數的參數是一個有兩個參數的函數。
這兩個參數一個是resove,用來在異步操作成功后調用,并把異步結果傳出去,調用resove后狀態就由pending->resolved。
另一個是reject,用來在失敗或異常時調用,并把錯誤消息傳出去,調用reject后狀態由pending->rejected

var promise = new Promise(function(resolve, reject) {
    
});

通常需要在成功或失敗后做一些操作,這時需要then來做這個事,then可以有兩個函數參數,第一個是成功后調用的,第二個是失敗調用的,第二個是可選的。
另外,then返回的也是一個Promise,不過不是原來的那個,而是新new出來的,這樣可以鏈式調用,then后面再接then。

// 函數參數用lambda表達式寫更簡潔promise.then(success => {    console.info(success);
}, error => {    console.info(error);
}).then(()=>console.info('finish'));

嵌套的Promise

在實際場景中,我們可能需要在一個異步操作后再接個異步操作,這樣就會有Promise的嵌套操作。
下面的代碼顯示的是Promise的嵌套操作:
p1先打印"start",延時兩秒打印"p1"。
p2p1完成后延時兩秒打印"p2"。

function delay(): Promise<void>{    return new Promise<void>((resolve, reject)=>{setTimeout(()=>resolve(), 2000)});
}let p1 = new Promise((resolve, reject) => {    console.info('start'); 
    delay().then(()=>{        console.info('p1'); 
        resolve()
    });
});let p2 = new Promise((resolve, reject) => {
    p1.then(()=>delay().then(()=>resolve()));
});

p2.then(()=>console.info('p2'));

異常處理

上面提到Promise出錯時把狀態變為rejected并把錯誤消息傳給reject函數,在then里面調用reject函數就可以顯示異常。
不過這樣寫顯得不是很友好,Promise還有個catch函數專門用來處理錯誤異常。
而且Promise的異常是冒泡傳遞的,最后面寫一個catch就可以捕獲到前面所有promise可能發生的異常,如果用reject就需要每個都寫。
所以reject函數一般就不需要在then里面寫,在后面跟個catch就可以了。

new Promise(function(resolve, reject) {  throw new Error('error');
}).catch(function(error) {  console.info(error); // Error: error});

也如上面所說狀態只有兩種變化且一旦變化就固定下來,所以如果已經在Promise里執行了resolve,再throw異常是沒用的,catch不到,因為狀態已經變成resolved

new Promise(function(resolve, reject) {
    resolve('success');    throw new Error('error');
}).catch(function(error) {    console.info(error); // 不會執行到這里});

另外,catch里的代碼也可能出異常,所以catch后面也還可以跟catch的議案。

new Promise(function(resolve, reject) {    throw new Error('error');
}).catch(function(error) {    console.info(error);  // Error: error
    throw new Error('catch error');
}).catch(function(error){    console.info(error); // Error: catch error   };

BlueBird的 finally 和 done

異常的try...catch后面可以跟finally來執行必須要執行的代碼,Promise原生并不支持,可以引入BlueBird的擴展庫來支持。
另外還有done在最后面來表示執行結束并拋出可能出現的異常,比如最后一個catch代碼塊里的異常。

let p = new Promise(function(resolve, reject) {
    x = 2;  // error, 沒有聲明x變量
    resolve('success');
}).catch(function(error) {    console.info(error); 
}).finally(()=>{ // 總會執行這里
    console.info('finish');
    y = 2;  // error, 沒有聲明y變量}).done(); 

try{
    p.then(()=>console.info('done'));
} catch (e){    console.info(e); // 由于最后面的done,所以會把finally里的異常拋出來,如果沒有done則不會執行到這里}

并行執行Promise

雖然JavaScript是單線程語言,但并不妨礙它執行一些IO并行操作,如不阻塞發出http request,然后異步等待。
Promise除了用then來順序執行外,也同樣可以不阻塞同時執行多個Promise然后等所有結果返回再進行后續操作。
C#的Task有個WhenAll的靜態方法來做這個事,Promise則是用all方法達到同樣目的。
all方法接受實現Iterator接口的對象,比如數組。

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

all返回的是一個新的Promise- p,p的狀態是由p1, p2, p3同時決定的:

p.resolved = p1.resolve && p2.resolve && p3.resolve
p.rejected = p1.rejected || p2.rejected || p3.rejected

也就是說p的成功需要p1,p2,p3都成功,而只要p1, p2, p3里有任何一個失敗則p失敗并退出。

Promise還有一個方法race同樣是并行執行多個Promise,不同于all的是它的成功狀態和錯誤狀態一樣,只要有一個成功就成功,如同C# Task的Any方法。

另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

本文標題:從C#到TypeScript-Promise-創新互聯
網頁鏈接:http://m.kartarina.com/article38/ccgopp.html

成都網站建設公司_創新互聯,為您提供營銷型網站建設、定制網站網站維護電子商務品牌網站制作、小程序開發

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

h5響應式網站建設
主站蜘蛛池模板: 亚洲国产成人精品无码区花野真一 | 久久久久亚洲AV无码去区首| 亚洲精品无码日韩国产不卡?V| 亚洲精品无码永久在线观看男男| 成人免费无码大片a毛片| 亚洲?V无码成人精品区日韩 | 国产精品午夜无码av体验区| 狠狠躁狠狠爱免费视频无码| 精品无码无人网站免费视频| 国产亚洲精品无码拍拍拍色欲 | 国产高清无码二区| 人妻丰满av无码中文字幕| 无码日韩人妻AV一区二区三区| 久久久无码精品亚洲日韩按摩 | 男人的天堂无码动漫AV| 国产av无码久久精品| 亚洲中文字幕无码av在线| 色欲A∨无码蜜臀AV免费播| 精品无码成人片一区二区| 精品少妇人妻av无码久久| 成人午夜精品无码区久久| 国产日产欧洲无码视频无遮挡| 少妇无码一区二区三区| 夜夜添无码试看一区二区三区| 韩国无码AV片在线观看网站| 中文字幕av无码无卡免费| 精品国产V无码大片在线看| 亚洲一区爱区精品无码| 亚洲精品无码久久千人斩| 天天看高清无码一区二区三区| 亚洲中文无码永久免| 麻豆国产精品无码视频| 亚洲国产精品无码久久久秋霞2| 亚洲国产精品无码久久SM| 成人午夜亚洲精品无码网站| 亚洲中文字幕无码不卡电影| 中文字字幕在线中文无码 | 特级小箩利无码毛片| 亚洲精品自偷自拍无码| 亚洲av日韩aⅴ无码色老头| 丰满少妇人妻无码专区|