Evo API Draft
  • Java
    • Intro
    • Imports
    • Constructing Objects
    • Properties
    • Type Annotations
    • Conversions
    • Explicit Conversions
    • Behaviors
    • Creating and Extending Types
    • Promises
  • mc-std
    • Intro
    • Commands
Powered by GitBook
On this page
  • CompleteableFuture
  • Callbacks
  • Lambda Methods
  • Lambda Arguments
  1. Java

Promises

Using Java methods with TypeScript's async support.

JavaScript (and thus TypeScript) is built on top of the idea of the event loop. Modern JavaScript has abstracted these asynchronous tasks into Promises, which can be nicely used with the await feature.

const response = await fetch(url);
const body = await response.text();
console.log(body);

Unfortunately, Java doesn't have such nice support for asynchronous operations. There are two primary ways APIs use asychronous support in Java. T

CompleteableFuture

The modern way is using the Java CompleteableFuture class.

CompletableFuture<HttpResponse<String>> future = HttpClient.newHttpClient()
    .sendAsync(
        HttpRequest.newBuilder()
            .uri(URI.create(url))
            .build(), 
        HttpResponse.BodyHandlers.ofString()
    );

future
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

As the CompleteableFuture class has similar semantics to JavaScript promises, Evo's Java API implicitly converts them to Promises for you.

// Why would you do this when Deno has its own native `fetch`?

const request = await HttpClient.newHttpClient()
    .sendAsync(
        HttpRequest.newBuilder()
            .uri(URI.create(url))
            .build(), 
        HttpResponse.BodyHandlers.ofString()
    );
    
console.log(await request.body());

Callbacks

The other way is using callbacks.

Lambda Methods

One way that callbacks are handled in Java is by constructing an interface with only one method to override (i.e. a lambda interface), and running an async method on that which runs the method once it's ready.

new BukkitRunnable(() => {
    console.log("Hi!");
})).runTaskLater(plugin, 0, 20);

Using the promises API though, this becomes much nicer.

await BukkitRunnable.promises.runTaskLater(plugin, 0, 20);
console.log("Hi!");

Lambda Arguments

The other way is to pass in a lambda to some other method that handles async behavior.

Bukkit.scheduler.runTaskLater(plugin, () => {
    console.log("Hi!");
}, 0, 20);

Fortunately, the promises API works for this too. It will use the first lambda interface argument (i.e. BukkitRunnable) as what to listen for when resolving the promise.

// Don't actually use this. TS has its own timeout functions.

await Bukkit.scheduler.runTaskLater.promises(plugin, 0, 20);
console.log("Hi!");
PreviousCreating and Extending TypesNextIntro

Last updated 2 years ago