DevGang
Авторизоваться

Представляем новое ключевое слово «using» в JavaScript (для переменных)

JavaScript только что добавил новое ключевое слово для создания переменной под названием using. Это ключевое слово является идеальной заменой let и const в определенных сценариях, таких как подключения к базе данных и обработка файлов.

Узнайте, что такое ключевое слово using и некоторые умные способы его использования в вашей программе JavaScript. Это ключевое слово навсегда изменит способ написания переменных в JavaScript.

Пример проблемного кода

Лучший способ понять ключевое слово using — выяснить, какой код оно пытается решить.

Допустим, у вас есть проект TypeScript со следующей структурой каталогов:

📦my-ts-project
 ┣ 📂.vscode
 ┣ 📂files
 ┃ ┗ 📜a.txt
 ┣ 📂other
 ┣ 📜package-lock.json
 ┣ 📜package.json
 ┣ 📜script.ts
 ┗ 📜tsconfig.json

Откройте файл script.ts в текстовом редакторе и включите следующий код:

function writeFile(path:string) {
  const file = fs.openSync(`files/${path}`, 'w+')

  fs.writeFileSync(file, "Text/n")

  fs.closeSync(file)
}

writeFile(a.txt)

Эта функция writeFile() принимает путь к файлу, в который мы хотим записать. Он открывает файл, записывает в него случайный текст и закрывается из этого файла (всегда закрывайте файл после операции записи, чтобы избежать открытия обработчиков нашего файла).

В последней строке мы вызвали функцию и передали ей «a.txt» в качестве аргумента. Прежде чем запускать код, убедитесь, что у вас есть файл .txt в папке files/.

Когда вы запускаете script.ts на терминале с помощью команды node script.ts, текст будет сохранен внутри файла a.txt, чтобы указать, что код работает.

Вот в чем проблема. Допустим, у нас есть файл temp.txt в папке files/, и в коде мы не хотим ничего делать, если путь, указанный функции, является временным файлом:

function writeFile(path:string) {
  const file = fs.openSync(`files/${path}`, 'w+')

  fs.writeFileSync(file, "Text/n")

  if(path.includes("temp")) {
    return
  }

  fs.writeSync(file, "Permanent")
  fs.closeSync(file)
}

writeFile(a.txt)
writeFile(temp.txt)

Под условием if мы должны записать в файл текст «Постоянно», если это не файл temp.txt.

Теперь, если вы сохраните файл, запустите код и проверите файл a.txt, вы увидите текст «Постоянно». Но вы не найдете его в файле temp.txt из-за оператора возврата условия if.

Вы можете подумать, что все работает нормально, но в работе этой программы есть огромная проблема. Поскольку мы **return** на полпути, на самом деле дело не доходит до момента закрытия файла.

Чтобы решить эту проблему, вам нужно вызвать метод closeSync() непосредственно перед возвратом функции, например:

function writeFile(path:string) {
  const file = fs.openSync(`files/${path}`, 'w+')
  fs.writeFileSync(file, "Text/n")

  if(path.includes("temp")) {
    fs.closeSync(file)
    return
  }

  fs.writeSync(file, "Permanent")
  fs.closeSync(file)
}

writeFile(a.txt)
writeFile(temp.txt)

В эту ошибку легко попасть, потому что вы можете легко забыть о закрытии соединения после раннего возвращения.

Итак, если у вас есть несколько подобных сценариев, когда вы возвращаетесь раньше или делаете другие разные вещи, вам придется скопировать «закрывающий код» в каждое место, куда вы возвращаетесь раньше.

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

Основы использования ключевых слов

Просто замените ключевое слово const на using при открытии файла:

function writeFile(path:string) {
  using file = fs.openSync(`files/${path}`, 'w+')

  // other code goes here
}

writeFile(a.txt)
writeFile(tempt.txt)

С помощью ключевого слова using, как только файл выйдет за пределы области видимости (поэтому у вас больше нет доступа к этой переменной и она будет очищена сборщиком мусора), он автоматически позаботится обо всем закрытии и очистке за вас.

Чтобы убедиться, что все это синхронизируется правильно, вам необходимо убедиться, что используемая вами переменная действительно настроена в правильном формате.

Итак, давайте продолжим и создадим функцию для открытия файла, чтобы мы могли выполнять всю эту дополнительную настройку «за кулисами».

В корневой папке вашего проекта создайте новый файл с именем openFile.ts. Внутри этого файла экспортируйте функцию openFile, которая в значительной степени отвечает за закрытие и очистку:

import fs from 'fs'

export function openFile() {
  const file = fs.openSync(`files/${path}`, 'w+')

  return {
    handle: file,
    [Symbol.dispose] () {
      console.log("Disposed")
      fs.closeSync(file)
    }
  }  
}

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

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

import { openFile } from "./openFile"

function writeFile(path:string) {
  using file = fs.openFile(path)

  fs.writeFileSync(file.handle, "Permanent")

  if(path.includes("temp")) {
    return
  }

  fs.writeSync(file.handle, "Permanent")

}

writeFile(a.txt)
writeFile(temp.txt)

Теперь, если вы сохраните файл и запустите код, вы заметите, что в вашей консоли дважды написано «Dispose». Это означает, что он фактически очищает ваши файлы.

Поэтому, как только мы либо вызываем return, либо доходим до конца функции, файл, определенный с помощью using, больше нигде не используется, поскольку его можно использовать только внутри функции.

В результате JavaScript достаточно умен, чтобы избавиться от кода и все очистить.

Заключение

С помощью ключевого слова using, как только переменная больше не доступна (т. е. выходит за пределы области видимости), она просто полностью удаляется, вызывая функцию очистки, которую вам необходимо определить для возврата функции symbol.dispose.

Ключевое слово using очень важно, если вы выполняете соединение с базой данных, соединение WebSocket или соединение любого другого типа, когда вам необходимо их закрыть или отключить. Это очень простой и понятный способ справиться с этим.

  Если вы новичок в изучении JavaScript и ищете лучший ресурс, который поможет в этом, ознакомьтесь с HTML to React: The Ultimate Guide.

Источник:

#JavaScript
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу