# Eclipse Vert.x
Как уже должно быть ясно к данному моменту, ES4X использует Vert.x для чтения/записи, а также как стандартную модель программирования. При этом ES4X предлагает несколько приятных улучшений по сравнению со стандартным Vert.x APIs (opens new window).
# Сгенерированные API
Все API, опубликованные в npm под пространством имён @vertx и @reactiverse, генерируются кодом. Генерация кода
помогает использовать эти API пользователями JavaScript в знакомом им формате и без компромиссов с производительностью
приложения.
Все взаимодействия с JVM происходят через Java-объекты. Самый важный нюанс - правильно передать JVM класс в JS:
// Импортируем java.lang.Math класс, чтобы использовать его
// как тип JS в скрипте
const Math = Java.type('javalang.Math');
Такой подход можно использовать для всех API, но есть несколько ограничений, которые ES4X пытается разрешить:
- Подверженность ошибкам - Необходимо точно знать Java API и необходимые типы для использования их в JavaScript.
- Невозможность задать зависимости - Если нужно использовать несколько API из разных модулей, импорт классов не позволяет задать зависимости между ними.
- Отсутствие поддержки IDE - Разработчику нужно узнать API перед тем, как начать его использовать, и IDE в этом не может помочь.
Генератор ES4X решает эти проблемы с помощью создания модуля npm для каждого модуля vertx и определений типов для
каждого класса.
Каждый модуль содержит следующие файлы:
package.json- Определяет зависимости между модулямиindex.js- Интерфейсы commonjs APIindex.mjs- Интерфейсы ESM APIindex.d.ts- Полные определения типов для интерфейсов APIenum.js- Перечисления commonjs APIenum.mjs- Перечисления ESM APIenum.d.ts- Полные определения типов для перечислений APIoptions.js- Data objects для commonjs APIoptions.mjs- Data objects для ESM APIoptions.d.ts- Полные определения типов для Data Objects API
Все файлы index упрощают загрузку JVM классов с помощью замены, например:
// без ES4X
const Router = Java.type('io.vertx.ext.web.Router');
// с ES4X
import { Router } from '@vertx/web';
Такая небольшая правка позволяет IDE помогать при разработке, а менеджерам пакетов - скачивать зависимости при
необходимости. Все файлы .d.ts подсказывают IDE типы и дают поддержку завершения кода.
# Promise/Future
В Vert.x есть 2 типа:
io.vertx.core.Futureio.vertx.core.Promise
Как ни странно, Vert.x Promise - это не то же самое, что JavaScript Future. Vert.x Promise - часть Vert.x Future
с доступом записи. В терминах JavaScript:
- Vert.x
Future=== JavaScriptPromise Like (Thenable) - Vert.x
Promise=== JavaScriptExecutor Function
# async/await
async/await поддерживается без каких-либо шагов компиляции GraalVM. ES4X добавляет новую возможность к типу Vert.x
Future. Те API, которые возвращают Vert.x Future, могут использоваться, как Thenable, а потому:
// используем Java API
vertx.createHttpServer()
.listen(0)
.onSuccess(server => {
console.log('Сервер готов!')
})
.onFailure(err => {
console.log('Запуск сервера завершен неудачно!')
});
Может использоваться, как Thenable:
try {
let server = await vertx
.createHttpServer()
.listen(0);
console.log('Сервер готов!');
} catch (err) {
console.log('Запуск сервера завершен неудачно!')
}
:::Совет
async/await работает даже с циклами, что сильно облегчает работу с асинхронным кодом, особенно при смешивании кода JS
и Java.
:::
# Приведение типов
Vert.x написан на Java, однако при работе с JavaScript пользователю не нужно так сильно заботиться о типах, как в
Java. ES4X выполняет некоторые приведения типов "из коробки":
| Java | TypeScript |
|---|---|
| void | void |
| boolean | boolean |
| byte | number |
| short | number |
| int | number |
| long | number |
| float | number |
| double | number |
| char | string |
| boolean[] | boolean[] |
| byte[] | number[] |
| short[] | number[] |
| int[] | number[] |
| long[] | number[] |
| float[] | number[] |
| double[] | number[] |
| char[] | string[] |
| java.lang.Void | void |
| java.lang.Object | any |
| java.lang.Boolean | boolean |
| java.lang.Double | number |
| java.lang.Float | number |
| java.lang.Integer | number |
| java.lang.Long | number |
| java.lang.Short | number |
| java.lang.Char | string |
| java.lang.String | string |
| java.lang.CharSequence | string |
| java.lang.Boolean[] | boolean[] |
| java.lang.Double[] | number[] |
| java.lang.Float[] | number[] |
| java.lang.Integer[] | number[] |
| java.lang.Long[] | number[] |
| java.lang.Short[] | number[] |
| java.lang.Char[] | string[] |
| java.lang.String[] | string[] |
| java.lang.CharSequence[] | string[] |
| java.lang.Object[] | any[] |
| java.lang.Iterable | any[] |
| java.util.function.BiConsumer | <T extends any, U extends any>(arg0: T, arg1: U) => void |
| java.util.function.BiFunction | <T extends any, U extends any, R extends any>(arg0: T, arg1: U) => R |
| java.util.function.BinaryOperator | <T extends any>(arg0: T, arg1: T) => T |
| java.util.function.BiPredicate | <T extends any, U extends any>(arg0: T, arg1: U) => boolean |
| java.util.function.Consumer | <T extends any>(arg0: T) => void |
| java.util.function.Function | <T extends any, R extends any>(arg0: T) => R |
| java.util.function.Predicate | <T extends any>(arg0: T) => boolean |
| java.util.function.Supplier | <T extends any>() => T |
| java.util.function.UnaryOperator | <T extends any>(arg0: T) => T |
| java.time.Instant | Date |
| java.time.LocalDate | Date |
| java.time.LocalDateTime | Date |
| java.time.ZonedDateTime | Date |
| java.lang.Iterable<T> | <T>[] |
| java.util.Collection<T> | <T>[] |
| java.util.List<T> | <T>[] |
| java.util.Map<K, V> | { [key: <K>]: <V> } |