From 2c08192cf237569bee2712aa5cb62f013501c583 Mon Sep 17 00:00:00 2001 From: Keita Urashima Date: Thu, 28 May 2026 11:30:09 +0900 Subject: [PATCH] DOC: document Context#perform_microtask_checkpoint Adds a "Microtask checkpoints" section explaining V8's auto-drain behavior and when manual draining is needed (Ruby callbacks invoked synchronously from JS, e.g. chained dispatchEvent listeners). Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index cfdac76..6c0b0b0 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,38 @@ Performance is slightly better than running `context.eval("hello('George')")` si * compilation of eval'd string is avoided * function arguments don't need to be converted to JSON +### Microtask checkpoints + +V8 drains its microtask queue (e.g. callbacks queued via `Promise.resolve().then(...)`) automatically when script execution returns to the embedder, so most code "just works": + +```ruby +context = MiniRacer::Context.new +context.eval(<<~JS) + let x = 0; + Promise.resolve().then(() => x = 99); +JS +context.eval("x") +# => 99 +``` + +When JavaScript invokes a Ruby callback synchronously and you need queued microtasks to drain mid-execution — e.g. for spec-compliant ordering across a chain of synchronous `dispatchEvent` listeners — call `context.perform_microtask_checkpoint` from the callback: + +```ruby +context = MiniRacer::Context.new +context.attach("drain", -> { context.perform_microtask_checkpoint }) +context.eval(<<~JS) + globalThis.log = []; + Promise.resolve().then(() => log.push("microtask")); + log.push("before"); + drain(); + log.push("after"); +JS +context.eval("log") +# => ["before", "microtask", "after"] +``` + +Without `drain()` the order would be `["before", "after", "microtask"]` because the microtask only runs once the outermost script returns. `perform_microtask_checkpoint` is a thin wrapper over V8's `MicrotasksScope::PerformCheckpoint`. + ## Performance The `bench` folder contains benchmark.