解读TypeScript 5.2(一)——— using关键字

190 阅读2分钟

关于ts

首先,点进这个文章的多多少少都会对TypeScript有了解,最近TypeScript文档刚刚更新了5.2版本的内容,其中using关键字是我认为最大的更新之一。

关于using

using的诞生是为了解决一个问题创建对象后通常需要执行某种“清理”。在js中即将要推出一个新的概念显式资源管理,这个具体是做什么用的呢。

显式资源管理,在我们写代码的过程中会遇到一些内存清理的问题,比如网络连接、临时文件或者一些需要手动释放的内存I/O。在这里js给了我们一个语法来解决这个问题finally,让我们先来看一下他的具体用法。

function * g() {
 const handle = acquireFileHandle(); // critical resource
 try {
   
 }
 finally {
   handle.release(); // cleanup
 }
}

const obj = g();
try {
 const r = obj.next();
 
}
finally {
 obj.return(); // calls finally blocks in `g`
}

这里我用一个官方的案例来说一下他的作用,首先我们在写代码的过程中多多少少会用到一些异步的变量,他们存储这比如文件或者接口的东西,这些东西在结束生命周期之后需要手动释放内存,finally其实就是做这个功能的。当然这个功能在c#,java,py中都有类似的语法。

using的使用

我们已经知道了异步显式资源管理的概念,也知道了using的目的是为了解决这个问题,下面我来介绍一下他的api。这首先添加一个名为 的新内置函数,我们可以使用由 命名的方法创建对象。 为了方便起见,TypeScript 定义了一个名为的新全局类型来描述这些。symbol Symbol.dispose Symbol.dispose Disposable.

image.png 如果我们想使用这个类需要在tsconfig中配置一下。

 "lib": ["ESNext", "esnext.disposable"],   

下面我们通过类比using和finally看一下using的用法。

//TempFile类
class TempFile implements Disposable {
    #path: string;
    #handle: number;
    constructor(path: string) {
        this.#path = path;
        this.#handle = fs.openSync(path, "w+");
    }
    // other methods
    [Symbol.dispose]() {
        // Close the file and delete it.
        fs.closeSync(this.#handle);
        fs.unlinkSync(this.#path);
    }
}
//finally的用法
export function doSomeWork() {
    const file = new TempFile(".some_temp_file");
    try {
        // ...
    }
    finally {
        file[Symbol.dispose]();
    }
}
//using的用法
export function doSomeWork() {
    using file = new TempFile(".some_temp_file");
    // use file...
    if (someCondition()) {
        // do some more work...
        return;
    }
}

通过对比发现using内部其实就是在生命周期的末尾调用了[Symbol.dispose]来进行内存清除。这里# ECMAScript 显式资源管理这篇讲的非常好,但是目前es还不支持这个语法,只有ts支持了。