summaryrefslogtreecommitdiff
path: root/core/01_core.js
diff options
context:
space:
mode:
Diffstat (limited to 'core/01_core.js')
-rw-r--r--core/01_core.js97
1 files changed, 66 insertions, 31 deletions
diff --git a/core/01_core.js b/core/01_core.js
index 6a6696bf8..bea9c4290 100644
--- a/core/01_core.js
+++ b/core/01_core.js
@@ -326,41 +326,76 @@
}
const InterruptedPrototype = Interrupted.prototype;
- const promiseHooks = {
- init: [],
- before: [],
- after: [],
- resolve: [],
- hasBeenSet: false,
- };
+ const promiseHooks = [
+ [], // init
+ [], // before
+ [], // after
+ [], // resolve
+ ];
function setPromiseHooks(init, before, after, resolve) {
- if (init) ArrayPrototypePush(promiseHooks.init, init);
- if (before) ArrayPrototypePush(promiseHooks.before, before);
- if (after) ArrayPrototypePush(promiseHooks.after, after);
- if (resolve) ArrayPrototypePush(promiseHooks.resolve, resolve);
+ const hooks = [init, before, after, resolve];
+ for (let i = 0; i < hooks.length; i++) {
+ const hook = hooks[i];
+ // Skip if no callback was provided for this hook type.
+ if (hook == null) {
+ continue;
+ }
+ // Verify that the type of `hook` is a function.
+ if (typeof hook !== "function") {
+ throw new TypeError(`Expected function at position ${i}`);
+ }
+ // Add the hook to the list.
+ ArrayPrototypePush(promiseHooks[i], hook);
+ }
- if (!promiseHooks.hasBeenSet) {
- promiseHooks.hasBeenSet = true;
+ const wrappedHooks = ArrayPrototypeMap(promiseHooks, (hooks) => {
+ switch (hooks.length) {
+ case 0:
+ return undefined;
+ case 1:
+ return hooks[0];
+ case 2:
+ return create2xHookWrapper(hooks[0], hooks[1]);
+ case 3:
+ return create3xHookWrapper(hooks[0], hooks[1], hooks[2]);
+ default:
+ return createHookListWrapper(hooks);
+ }
- ops.op_set_promise_hooks((promise, parentPromise) => {
- for (let i = 0; i < promiseHooks.init.length; ++i) {
- promiseHooks.init[i](promise, parentPromise);
- }
- }, (promise) => {
- for (let i = 0; i < promiseHooks.before.length; ++i) {
- promiseHooks.before[i](promise);
- }
- }, (promise) => {
- for (let i = 0; i < promiseHooks.after.length; ++i) {
- promiseHooks.after[i](promise);
- }
- }, (promise) => {
- for (let i = 0; i < promiseHooks.resolve.length; ++i) {
- promiseHooks.resolve[i](promise);
- }
- });
- }
+ // The following functions are used to create wrapper functions that call
+ // all the hooks in a list of a certain length. The reason to use a
+ // function that creates a wrapper is to minimize the number of objects
+ // captured in the closure.
+ function create2xHookWrapper(hook1, hook2) {
+ return function (promise, parent) {
+ hook1(promise, parent);
+ hook2(promise, parent);
+ };
+ }
+ function create3xHookWrapper(hook1, hook2, hook3) {
+ return function (promise, parent) {
+ hook1(promise, parent);
+ hook2(promise, parent);
+ hook3(promise, parent);
+ };
+ }
+ function createHookListWrapper(hooks) {
+ return function (promise, parent) {
+ for (let i = 0; i < hooks.length; i++) {
+ const hook = hooks[i];
+ hook(promise, parent);
+ }
+ };
+ }
+ });
+
+ ops.op_set_promise_hooks(
+ wrappedHooks[0],
+ wrappedHooks[1],
+ wrappedHooks[2],
+ wrappedHooks[3],
+ );
}
// Extra Deno.core.* exports