Pull to refresh

Comments 9

PinnedPinned comments

Если сходить не в какую-то статью, а в блог самого TypeScript, то можно найти там вторую - и очень важную часть нововведения: DisposableStack и AsyncDisposableStack. С их помощью можно подчищать ресурсы, у которых ещё нет своего метода @@dispose/@@asyncDispose.

function doSomeWork() {
    const path = ".some_temp_file";
    const file = fs.openSync(path, "w+");

    using cleanup = new DisposableStack();
    cleanup.defer(() => {
        fs.closeSync(file);
        fs.unlinkSync(path);
    });

    // use file...

    if (someCondition()) {
        // do some more work...
        return;
    }

    // ...
}

Точнее будет сказать, RAII. Реализация скорее похожа не на деструкторы C++, а на with в Python и using в C#.

Если сходить не в какую-то статью, а в блог самого TypeScript, то можно найти там вторую - и очень важную часть нововведения: DisposableStack и AsyncDisposableStack. С их помощью можно подчищать ресурсы, у которых ещё нет своего метода @@dispose/@@asyncDispose.

function doSomeWork() {
    const path = ".some_temp_file";
    const file = fs.openSync(path, "w+");

    using cleanup = new DisposableStack();
    cleanup.defer(() => {
        fs.closeSync(file);
        fs.unlinkSync(path);
    });

    // use file...

    if (someCondition()) {
        // do some more work...
        return;
    }

    // ...
}

Плюс, там же написана ещё одна важная вещь: TypeScript не будет автоматически полифиллить сами Symbol.dispose, Symbol.asyncDispose, DisposableStack, AsyncDisposableStack. Полифиллы нужно подключать самому. Если стеки не нужны, а нужен только using, можно сделать просто:

Symbol.dispose ??= new Symbol("Symbol.dispose");
Symbol.asyncDispose ??= new Symbol("Symbol.asyncDispose");

И работает это все пока только с таргетом es2022 или ниже, и esnext или esnext.disposable в lib.

Если сходить не в какую-то статью, а в блог самого TypeScript

Ну кстати я сам удивился - статья от 16 июня, блог разрабов от 30 июня
Есть идеи, почему так?)

Возможно, автор следил за разработкой фичи в ишью на гитхабе, и писал ее, ориентируясь на информацию оттуда.

Т.е. с поведением в точности как деструкторы C++ объектов на стеке, я правильно понял? А по реализации это синтаксический сахар над try-finally?

Грубо говоря, да - уничтожаются тоже в обратном порядке при выходе из скоупа, включая выход по исключению. Вот здесь есть подробнее о семантике.

Главное отличие, кажется, в том, что происходит, если dispose выбросил исключение - здесь вызов деструкторов продолжается, а все выброшенные исключения комбинируются в одно и выбрасываются после.

Sign up to leave a comment.

Articles