• 
    

      <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
      1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>

        從C#到TypeScript-Promise-創(chuàng)新互聯(lián)

        從C#到TypeScript - Promise

        背景

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

        成都創(chuàng)新互聯(lián)是一家專業(yè)提供蘭陵企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站制作、html5、小程序制作等業(yè)務(wù)。10年已為蘭陵眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

        這篇先來看看Promise:

        Promise的特點(diǎn)

        Promise之于TypeScript,相當(dāng)于Task之于C#,只有返回Promise的函數(shù)才能使用async await。
        Promise其實(shí)就是一個(gè)可以獲取異步結(jié)果,并封裝了一些異步操作的對(duì)象。
        有三個(gè)狀態(tài):
        pending: 進(jìn)行中
        resolved: 成功
        rejected: 失敗
        并且這三個(gè)狀態(tài)只有兩種轉(zhuǎn)換:pending->resolved、pending->rejected,不是成功就是失敗,并沒有多余的狀態(tài)轉(zhuǎn)換。
        這兩種轉(zhuǎn)換都是由異步返回的結(jié)果給定的,成功取回?cái)?shù)據(jù)就是resolved,取數(shù)據(jù)出異常就是rejected。
        也因此,這轉(zhuǎn)換過后的結(jié)果就是固定的了,不可能在轉(zhuǎn)換過后還會(huì)變回pending或其他狀態(tài)。
        Promise不能在任務(wù)進(jìn)行中取消,只能等結(jié)果返回,這點(diǎn)上不如C#的Task,Task可以通過CancelTaskToken來取消任務(wù)。

        Promise的使用

        可以直接new一個(gè)Promise對(duì)象,構(gòu)造函數(shù)的參數(shù)是一個(gè)有兩個(gè)參數(shù)的函數(shù)。
        這兩個(gè)參數(shù)一個(gè)是resove,用來在異步操作成功后調(diào)用,并把異步結(jié)果傳出去,調(diào)用resove后狀態(tài)就由pending->resolved
        另一個(gè)是reject,用來在失敗或異常時(shí)調(diào)用,并把錯(cuò)誤消息傳出去,調(diào)用reject后狀態(tài)由pending->rejected

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

        通常需要在成功或失敗后做一些操作,這時(shí)需要then來做這個(gè)事,then可以有兩個(gè)函數(shù)參數(shù),第一個(gè)是成功后調(diào)用的,第二個(gè)是失敗調(diào)用的,第二個(gè)是可選的。
        另外,then返回的也是一個(gè)Promise,不過不是原來的那個(gè),而是新new出來的,這樣可以鏈?zhǔn)秸{(diào)用,then后面再接then。

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

        嵌套的Promise

        在實(shí)際場(chǎng)景中,我們可能需要在一個(gè)異步操作后再接個(gè)異步操作,這樣就會(huì)有Promise的嵌套操作。
        下面的代碼顯示的是Promise的嵌套操作:
        p1先打印"start",延時(shí)兩秒打印"p1"。
        p2p1完成后延時(shí)兩秒打印"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出錯(cuò)時(shí)把狀態(tài)變?yōu)?code>rejected并把錯(cuò)誤消息傳給reject函數(shù),在then里面調(diào)用reject函數(shù)就可以顯示異常。
        不過這樣寫顯得不是很友好,Promise還有個(gè)catch函數(shù)專門用來處理錯(cuò)誤異常。
        而且Promise的異常是冒泡傳遞的,最后面寫一個(gè)catch就可以捕獲到前面所有promise可能發(fā)生的異常,如果用reject就需要每個(gè)都寫。
        所以reject函數(shù)一般就不需要在then里面寫,在后面跟個(gè)catch就可以了。

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

        也如上面所說狀態(tài)只有兩種變化且一旦變化就固定下來,所以如果已經(jīng)在Promise里執(zhí)行了resolve,再throw異常是沒用的,catch不到,因?yàn)闋顟B(tài)已經(jīng)變成resolved。

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

        另外,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來執(zhí)行必須要執(zhí)行的代碼,Promise原生并不支持,可以引入BlueBird的擴(kuò)展庫來支持。
        另外還有done在最后面來表示執(zhí)行結(jié)束并拋出可能出現(xiàn)的異常,比如最后一個(gè)catch代碼塊里的異常。

        let p = new Promise(function(resolve, reject) {
            x = 2;  // error, 沒有聲明x變量
            resolve('success');
        }).catch(function(error) {    console.info(error); 
        }).finally(()=>{ // 總會(huì)執(zhí)行這里
            console.info('finish');
            y = 2;  // error, 沒有聲明y變量}).done(); 
        
        try{
            p.then(()=>console.info('done'));
        } catch (e){    console.info(e); // 由于最后面的done,所以會(huì)把finally里的異常拋出來,如果沒有done則不會(huì)執(zhí)行到這里}

        并行執(zhí)行Promise

        雖然JavaScript是單線程語言,但并不妨礙它執(zhí)行一些IO并行操作,如不阻塞發(fā)出http request,然后異步等待。
        Promise除了用then來順序執(zhí)行外,也同樣可以不阻塞同時(shí)執(zhí)行多個(gè)Promise然后等所有結(jié)果返回再進(jìn)行后續(xù)操作。
        C#的Task有個(gè)WhenAll的靜態(tài)方法來做這個(gè)事,Promise則是用all方法達(dá)到同樣目的。
        all方法接受實(shí)現(xiàn)Iterator接口的對(duì)象,比如數(shù)組。

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

        all返回的是一個(gè)新的Promise- p,p的狀態(tài)是由p1, p2, p3同時(shí)決定的:

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

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

        Promise還有一個(gè)方法race同樣是并行執(zhí)行多個(gè)Promise,不同于all的是它的成功狀態(tài)和錯(cuò)誤狀態(tài)一樣,只要有一個(gè)成功就成功,如同C# Task的Any方法。

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

        本文標(biāo)題:從C#到TypeScript-Promise-創(chuàng)新互聯(lián)
        網(wǎng)頁鏈接:http://www.jbt999.com/article38/ccgopp.html

        成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)定制網(wǎng)站、網(wǎng)站維護(hù)、電子商務(wù)、品牌網(wǎng)站制作小程序開發(fā)

        廣告

        聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

        h5響應(yīng)式網(wǎng)站建設(shè)

      2. 
        

          <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
          1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>
            999激情 | 成人网站男人的天堂 | 操b在线看 | 天天操天天日天天插 | 亚洲欧美成人网站 | 青青草国产激情 | 国产精品偷窥熟女精品视 | 青青精品视频 | 日韩在线播放视频 | 免费操逼网站直接入看泡芙视频 |