Add window.queueMicrotask (#2844)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2019-08-31 12:16:30 -07:00 committed by Ryan Dahl
parent 07c3c76d0d
commit fdd4252d49
5 changed files with 49 additions and 0 deletions

View file

@ -455,6 +455,16 @@ void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(output);
}
void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
if (!(args[0]->IsFunction())) {
ThrowInvalidArgument(isolate);
return;
}
isolate->EnqueueMicrotask(args[0].As<v8::Function>());
}
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@ -493,6 +503,15 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
CHECK(core_val->SetAccessor(context, deno::v8_str("shared"), Shared)
.FromJust());
// Direct bindings on `window`.
auto queue_microtask_tmpl =
v8::FunctionTemplate::New(isolate, QueueMicrotask);
auto queue_microtask_val =
queue_microtask_tmpl->GetFunction(context).ToLocalChecked();
CHECK(
global->Set(context, deno::v8_str("queueMicrotask"), queue_microtask_val)
.FromJust());
}
void MessageCallback(v8::Local<v8::Message> message,

View file

@ -156,6 +156,7 @@ void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
void Shared(v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
void MessageCallback(v8::Local<v8::Message> message, v8::Local<v8::Value> data);
void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args);
static intptr_t external_references[] = {
reinterpret_cast<intptr_t>(Print),
reinterpret_cast<intptr_t>(Recv),
@ -164,6 +165,7 @@ static intptr_t external_references[] = {
reinterpret_cast<intptr_t>(ErrorToJSON),
reinterpret_cast<intptr_t>(Shared),
reinterpret_cast<intptr_t>(MessageCallback),
reinterpret_cast<intptr_t>(QueueMicrotask),
0};
static const deno_buf empty_buf = {nullptr, 0};

View file

@ -89,6 +89,7 @@ window.onload = undefined as undefined | Function;
// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
// yet incorporate the SubtleCrypto interface as its "subtle" property.
window.crypto = (csprng as unknown) as Crypto;
// window.queueMicrotask added by hand to self-maintained lib.deno_runtime.d.ts
// When creating the runtime type library, we use modifications to `window` to
// determine what is in the global namespace. When we put a class in the

View file

@ -77,3 +77,29 @@ test(function DenoNamespaceImmutable(): void {
// @ts-ignore
assert(print === Deno.core.print);
});
test(async function windowQueueMicrotask(): Promise<void> {
let resolve1: () => void | undefined;
let resolve2: () => void | undefined;
let microtaskDone = false;
const p1 = new Promise(
(res): void => {
resolve1 = (): void => {
microtaskDone = true;
res();
};
}
);
const p2 = new Promise(
(res): void => {
resolve2 = (): void => {
assert(microtaskDone);
res();
};
}
);
window.queueMicrotask(resolve1!);
setTimeout(resolve2!, 0);
await p1;
await p2;
});

View file

@ -1264,6 +1264,7 @@ declare interface Window {
callback: (event: domTypes.Event) => void | null,
options?: boolean | domTypes.EventListenerOptions | undefined
) => void;
queueMicrotask: (task: () => void) => void;
Deno: typeof Deno;
}