Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
async_hooks: add thisArg to AsyncResource.bind
Semver-major

Support setting the `thisArg` for AsyncResource.bind and
AsyncResource.prototype.bind. If `thisArg` is not set,
then `this` will be set to the `AsyncResource` instance.

Fixes: #36051
Signed-off-by: James M Snell <jasnell@gmail.com>
  • Loading branch information
jasnell committed Jan 6, 2021
commit 25d1319895f29d7381e7209f89ad753b1bf50158
14 changes: 12 additions & 2 deletions doc/api/async_hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -730,30 +730,40 @@ class DBQuery extends AsyncResource {
}
```

#### Static method: `AsyncResource.bind(fn[, type])`
#### Static method: `AsyncResource.bind(fn[, type, [thisArg]])`
Comment thread
jasnell marked this conversation as resolved.
Outdated
<!-- YAML
added:
- v14.8.0
- v12.19.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/36782
description: Added optional thisArg.
-->

* `fn` {Function} The function to bind to the current execution context.
* `type` {string} An optional name to associate with the underlying
`AsyncResource`.
* `thisArg` {any}

Binds the given function to the current execution context.

The returned function will have an `asyncResource` property referencing
the `AsyncResource` to which the function is bound.

#### `asyncResource.bind(fn)`
#### `asyncResource.bind(fn[, thisArg])`
<!-- YAML
added:
- v14.8.0
- v12.19.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/36782
description: Added optional thisArg.
-->

* `fn` {Function} The function to bind to the current `AsyncResource`.
* `thisArg` {any}

Binds the given function to execute to this `AsyncResource`'s scope.

Expand Down
13 changes: 9 additions & 4 deletions lib/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,15 @@ class AsyncResource {
return this[trigger_async_id_symbol];
}

bind(fn) {
bind(fn, thisArg = this) {
if (typeof fn !== 'function')
throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
const ret = FunctionPrototypeBind(this.runInAsyncScope, this, fn);
const ret =
FunctionPrototypeBind(
this.runInAsyncScope,
this,
fn,
thisArg);
ObjectDefineProperties(ret, {
'length': {
configurable: true,
Expand All @@ -241,9 +246,9 @@ class AsyncResource {
return ret;
}

static bind(fn, type) {
static bind(fn, type, thisArg) {
type = type || fn.name;
return (new AsyncResource(type || 'bound-anonymous-fn')).bind(fn);
return (new AsyncResource(type || 'bound-anonymous-fn')).bind(fn, thisArg);
}
}

Expand Down
16 changes: 16 additions & 0 deletions test/parallel/test-asyncresource-bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ setImmediate(() => {
assert.strictEqual(asyncResource.asyncId(), fn2());
assert.notStrictEqual(asyncId, fn2());
});

const foo = {};
const fn3 = asyncResource.bind(common.mustCall(function() {
assert.strictEqual(this, foo);
}), foo);
fn3();

const fn4 = asyncResource.bind(common.mustCall(function() {
assert.strictEqual(this, asyncResource);
}));
fn4();

const fn5 = asyncResource.bind(common.mustCall(function() {
assert.strictEqual(this, false);
}), false);
fn5();