Promise and Async/Await
Async code in RustScript uses the same async/await syntax as TypeScript. Under the hood, it compiles to tokio, Rust's standard async runtime.
async / await
async function fetchData(): string {
const result = await someAsyncOperation();
return result;
}
Generates:
async fn fetch_data() -> String {
let result = some_async_operation().await;
result
}
async main
If your program uses async operations, make main async:
async function main() {
const data = await fetchData();
console.log(data);
}
The compiler adds #[tokio::main] to the generated Rust, bootstrapping the tokio runtime.
Promise.all
Run multiple async operations concurrently:
async function fetchA(): string { return "a"; }
async function fetchB(): string { return "b"; }
async function main() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
console.log(`${a}, ${b}`);
}
Generates tokio::join!(fetchA(), fetchB()), running both futures concurrently on the tokio runtime.
Promise.allSettled
Like Promise.all but doesn't short-circuit on failure:
const results = await Promise.allSettled([fetchA(), fetchB()]);
Generates tokio::join! with Result wrapping, so all operations complete regardless of individual failures.
Promise.resolve / Promise.reject
const value = await Promise.resolve("hello"); // async { "hello" }
const error = await Promise.reject("failed"); // async { panic!("failed") }
new Promise
The constructor pattern for wrapping callback-based APIs:
const result = await new Promise((resolve, reject) => {
// resolve("value") to fulfill
// reject("error") to fail
});
Compiles to a tokio::oneshot channel.
Timers
// Delay execution
setTimeout(() => {
console.log("delayed");
}, 1000);
// Repeated execution
const handle = setInterval(() => {
console.log("tick");
}, 500);
// Cancel
clearInterval(handle);
setTimeout compiles to tokio::time::sleep + tokio::spawn. setInterval compiles to a tokio::time::interval loop. Cancellation uses handle.abort().
Real-world pattern: concurrent HTTP requests
import { get } from "reqwest";
async function fetchUsers(): string {
const response = await get("https://api.example.com/users");
return await response.text();
}
async function fetchPosts(): string {
const response = await get("https://api.example.com/posts");
return await response.text();
}
async function main() {
// Fetch both concurrently
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
console.log(`Users: ${users}`);
console.log(`Posts: ${posts}`);
}
How it maps to Rust
| RustScript | Rust |
|-----------|------|
| async function f() | async fn f() |
| await expr | expr.await |
| Promise.all([a, b]) | tokio::join!(a, b) |
| Promise.allSettled([a, b]) | tokio::join! with Result wrapping |
| Promise.resolve(v) | async { v } |
| Promise.reject(e) | async { panic!(e) } |
| new Promise((res, rej) => ...) | tokio::oneshot channel |
| setTimeout(fn, ms) | tokio::time::sleep + spawn |
| setInterval(fn, ms) | tokio::time::interval loop |