Skip to content

Commit 8d496b3

Browse files
committed
Add queueMicrotask
Ref: #16
1 parent 1fcb573 commit 8d496b3

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ test: build
6464
$(QJS) tests/test_loop.js
6565
$(QJS) tests/test_std.js
6666
$(QJS) tests/test_worker.js
67+
$(QJS) tests/test_queue_microtask.js
6768

6869
test262: build
6970
$(RUN262) -m -c test262.conf -a

quickjs.c

+17
Original file line numberDiff line numberDiff line change
@@ -33745,6 +33745,22 @@ static JSValue js_global_isFinite(JSContext *ctx, JSValueConst this_val,
3374533745
return JS_NewBool(ctx, res);
3374633746
}
3374733747

33748+
static JSValue js_microtask_job(JSContext *ctx,
33749+
int argc, JSValueConst *argv)
33750+
{
33751+
return JS_Call(ctx, argv[0], ctx->global_obj, 0, NULL);
33752+
}
33753+
33754+
static JSValue js_global_queueMicrotask(JSContext *ctx, JSValueConst this_val,
33755+
int argc, JSValueConst *argv)
33756+
{
33757+
if (check_function(ctx, argv[0]))
33758+
return JS_EXCEPTION;
33759+
if (JS_EnqueueJob(ctx, js_microtask_job, 1, &argv[0]))
33760+
return JS_EXCEPTION;
33761+
return JS_UNDEFINED;
33762+
}
33763+
3374833764
/* Object class */
3374933765

3375033766
static JSValue JS_ToObject(JSContext *ctx, JSValueConst val)
@@ -45683,6 +45699,7 @@ static const JSCFunctionListEntry js_global_funcs[] = {
4568345699
JS_CFUNC_DEF("parseFloat", 1, js_parseFloat ),
4568445700
JS_CFUNC_DEF("isNaN", 1, js_global_isNaN ),
4568545701
JS_CFUNC_DEF("isFinite", 1, js_global_isFinite ),
45702+
JS_CFUNC_DEF("queueMicrotask", 1, js_global_queueMicrotask ),
4568645703

4568745704
JS_CFUNC_MAGIC_DEF("decodeURI", 1, js_global_decodeURI, 0 ),
4568845705
JS_CFUNC_MAGIC_DEF("decodeURIComponent", 1, js_global_decodeURI, 1 ),

tests/test_queue_microtask.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
function assert(actual, expected, message) {
2+
if (arguments.length == 1)
3+
expected = true;
4+
5+
if (actual === expected)
6+
return;
7+
8+
if (actual !== null && expected !== null
9+
&& typeof actual == 'object' && typeof expected == 'object'
10+
&& actual.toString() === expected.toString())
11+
return;
12+
13+
throw Error("assertion failed: got |" + actual + "|" +
14+
", expected |" + expected + "|" +
15+
(message ? " (" + message + ")" : ""));
16+
}
17+
18+
function assert_throws(expected_error, func)
19+
{
20+
var err = false;
21+
try {
22+
func();
23+
} catch(e) {
24+
err = true;
25+
if (!(e instanceof expected_error)) {
26+
throw Error("unexpected exception type");
27+
}
28+
}
29+
if (!err) {
30+
throw Error("expected exception");
31+
}
32+
}
33+
34+
function assert_array_equals(a, b) {
35+
if (!Array.isArray(a) || !Array.isArray(b))
36+
return assert(false);
37+
38+
assert(a.length === b.length);
39+
40+
a.forEach((value, idx) => {
41+
assert(b[idx] === value);
42+
});
43+
}
44+
45+
// load more elaborate version of assert if available
46+
try { std.loadScript("test_assert.js"); } catch(e) {}
47+
48+
function test_types() {
49+
assert_throws(TypeError, () => queueMicrotask(), "no argument");
50+
assert_throws(TypeError, () => queueMicrotask(undefined), "undefined");
51+
assert_throws(TypeError, () => queueMicrotask(null), "null");
52+
assert_throws(TypeError, () => queueMicrotask(0), "0");
53+
assert_throws(TypeError, () => queueMicrotask({ handleEvent() { } }), "an event handler object");
54+
assert_throws(TypeError, () => queueMicrotask("window.x = 5;"), "a string");
55+
}
56+
57+
function test_async() {
58+
let called = false;
59+
queueMicrotask(() => {
60+
called = true;
61+
});
62+
assert(!called);
63+
}
64+
65+
function test_arguments() {
66+
queueMicrotask(function () { // note: intentionally not an arrow function
67+
assert(arguments.length === 0);
68+
}, "x", "y");
69+
};
70+
71+
function test_async_order() {
72+
const happenings = [];
73+
Promise.resolve().then(() => happenings.push("a"));
74+
queueMicrotask(() => happenings.push("b"));
75+
Promise.reject().catch(() => happenings.push("c"));
76+
queueMicrotask(() => {
77+
assert_array_equals(happenings, ["a", "b", "c"]);
78+
});
79+
}
80+
81+
test_types();
82+
test_async();
83+
test_arguments();
84+
test_async_order();

0 commit comments

Comments
 (0)