Skip to content

Commit b12d552

Browse files
authored
feat: queueMicrotask support (#291)
1 parent 4f0c82b commit b12d552

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

NativeScript/runtime/Runtime.mm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ void DisposeIsolateWhenPossible(Isolate* isolate) {
193193
DefinePerformanceObject(isolate, globalTemplate);
194194
DefineTimeMethod(isolate, globalTemplate);
195195
DefineDrainMicrotaskMethod(isolate, globalTemplate);
196+
// queueMicrotask(callback) per spec
197+
{
198+
Local<FunctionTemplate> qmtTemplate = FunctionTemplate::New(
199+
isolate, [](const FunctionCallbackInfo<Value>& info) {
200+
auto* isolate = info.GetIsolate();
201+
if (info.Length() < 1 || !info[0]->IsFunction()) {
202+
isolate->ThrowException(Exception::TypeError(
203+
tns::ToV8String(isolate, "queueMicrotask: callback must be a function")));
204+
return;
205+
}
206+
v8::Local<v8::Function> cb = info[0].As<v8::Function>();
207+
isolate->EnqueueMicrotask(cb);
208+
});
209+
globalTemplate->Set(tns::ToV8String(isolate, "queueMicrotask"), qmtTemplate);
210+
}
196211
ObjectManager::Init(isolate, globalTemplate);
197212
// SetTimeout::Init(isolate, globalTemplate);
198213
MetadataBuilder::RegisterConstantsOnGlobalObject(isolate, globalTemplate, isWorker);

TestRunner/app/tests/RuntimeImplementedAPIs.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,37 @@ describe("Performance object", () => {
4444
expect(Math.abs(dateNow - performanceAccurateNow)).toBeLessThan(10);
4545
});
4646
});
47+
48+
describe("queueMicrotask", () => {
49+
it("should be defined as a function", () => {
50+
expect(typeof queueMicrotask).toBe("function");
51+
});
52+
53+
it("should throw TypeError when callback is not a function", () => {
54+
expect(() => queueMicrotask(null)).toThrow();
55+
expect(() => queueMicrotask(42)).toThrow();
56+
expect(() => queueMicrotask({})).toThrow();
57+
});
58+
59+
it("runs after current stack but before setTimeout(0)", (done) => {
60+
const order = [];
61+
queueMicrotask(() => order.push("microtask"));
62+
setTimeout(() => {
63+
order.push("timeout");
64+
expect(order).toEqual(["microtask", "timeout"]);
65+
done();
66+
}, 0);
67+
expect(order.length).toBe(0);
68+
});
69+
70+
it("preserves ordering with Promise microtasks", (done) => {
71+
const order = [];
72+
queueMicrotask(() => order.push("qm1"));
73+
Promise.resolve().then(() => order.push("p"));
74+
queueMicrotask(() => order.push("qm2"));
75+
setTimeout(() => {
76+
expect(order).toEqual(["qm1", "p", "qm2"]);
77+
done();
78+
}, 0);
79+
});
80+
});

0 commit comments

Comments
 (0)