【TypeScript】如何在TypeScript中使用async/await,讓你的代碼更像C#。

【TypeScript】如何在TypeScript中使用async/await,讓你的代碼更像C#。

async/await

提到這個東西,大家應該都很熟悉。最出名的可能就是C#中的,但也有其它語言也實現。比如,Python 3.5中、比如Js中的yield/generator。

Typescript 當前版本1.8.x,1.7版本開始支持async/await, 當然只支持es6編譯。2.1版本說是將支持到es5/es3.


Typescript Roadmap : https://github.com/Microsoft/TypeScript/wiki/Roadmap

優點

在這種方式之前,我們主要用的方式,就是回調方式。但如果,你的當前這個調用依賴於回調的數據,當這種關係依賴的多些時候,想想你的代碼。

有了 async/await的方式,可以讓異步的調用,用起來像同步一樣。

場景

想一下這樣的場景,有三個http請求,每一個都要依賴上一個請求的返回結果。

我們用js在node中,模擬一下這樣的場景。

let http = require('http');

function test() {
    http.get('http://www.baidu.com', function (res) {
        console.log('the first Status :' + res.statusCode);
        http.get('http://www.163.com', function (res2) {
            console.log('the second Status :' + res2.statusCode);
            http.get('http://www.sina.com', function (res3) {
                console.log('the third Status :' + res3.statusCode);
            })
        })
    });
}

test();

我們再來看一下 Typescript 中,用 async/await 的方式。


import http = require('http');

class httpAsync {
    constructor() {

    }

    public async GetAsync(url: string): Promise<http.IncomingMessage> {
        var promise = new Promise<http.IncomingMessage>(resolve => {
            http.get(url, res => {
                resolve(res);
            });
        });

        return promise;
    }
}

async function test() {
    let ha = new httpAsync();

    let res = await ha.GetAsync("http://www.baidu.com");
    console.log('the first Status :' + res.statusCode);
    res = await ha.GetAsync("http://www.163.com");
    console.log('the first Status :' + res.statusCode);
    res = await ha.GetAsync("http://www.sina.com");
    console.log('the first Status :' + res.statusCode);
}

test();

我們封裝了一個httpAsync類,用async方式包裝了一下,

對比一個 兩個test方法內容,你覺得哪種方式更舒服一些。

如何實現

對C#熟悉的同學,可能很好的理解,因爲Promise很像C#中的TaskCompletionSource<T>.

我們來一段 C# 模擬實現這個功能的, C#中的HttpClient本身是支持async/await模式的,大家不要糾結這個,這裏只是模擬這個方式 .


    public class HttpAsync
    {
        public Task<HttpResponseMessage> GetAsync(string url)
        {
            TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();

            HttpClient hc = new HttpClient();

            hc.GetAsync(url).ContinueWith(res =>
            {
                tcs.SetResult(res.Result);
                hc.Dispose();
            });

            return tcs.Task;
        }
    }

C# 這方面感興趣的同學,可以去查查,網上的資料很多。

Typescript 實現這種方式,主要是一個關鍵字 async 和一個對象 Promise<T> .


import http = require('http');

class httpAsync {
    constructor() {

    }

    public async GetAsync(url: string): Promise<http.IncomingMessage> {
        var promise = new Promise<http.IncomingMessage>(resolve => {
            http.get(url, res => {
                resolve(res);
            });
        });

        return promise;
    }
}
  • 方法必須用 async 來標記。
  • 可以被 await 的方法必須有返回值 Promise<T> ,如果你的返回值是 void ,那麼方法的返回值就是 Promise<void> .
  • Promise<T> 包裝你的調用,當成功時調用__resolve__ 回調 結果Promise<T> ,來確定你的異步完成。
  • 可以在 Promise 構造中,再追加一個 reject 參數,來返回執行過程中的原因或錯誤。
  • Typescript 最終也會把 async/await 的方式編譯成 js 中類似 yield/generator 的方式

總結

看看 C#Typescript 的代碼,看起來很還是很像的吧。因爲他們的老爹都是一個人, C# 之父也是 Typescript 他爹。

在C#中,我們可能已很熟悉這種方式了,但是在 js/ts 中,我們使用的還不多,而且它也不像C#中提供全面的支持庫,使用的時候,可能還是得酌情處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章