Created
November 14, 2018 13:19
-
-
Save devsnek/8a01610ef4e1f0244f548997c60ffd4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const { | |
AsyncResource, | |
executionAsyncId, | |
createHook, | |
} = require('async_hooks'); | |
const EventEmitter = require('events'); | |
const util = require('util'); | |
const HasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); | |
const zones = new Map(); | |
class Zone extends EventEmitter { | |
#spec; | |
#resource; | |
#report; | |
constructor({ name = null, spec = {} } = {}) { | |
super(); | |
this.name = name; | |
this.#spec = spec; | |
this.#resource = new AsyncResource('ZONE', { | |
triggerAsyncId: executionAsyncId(), | |
requireManualDestroy: false, | |
}); | |
zones.set(this.#resource.asyncId(), this); | |
} | |
run(fn, thisArg, ...args) { | |
let r; | |
try { | |
r = this.#resource.runInAsyncScope(fn, thisArg, ...args); | |
if (r instanceof Promise) { | |
r.catch((err) => { | |
this.emit('error', err); | |
}); | |
} | |
} catch (err) { | |
this.emit('error', err); | |
} | |
return r; | |
} | |
get(name) { | |
return HasOwnProperty(this.#spec, name) ? this.#spec[name] : undefined; | |
} | |
fork({ name, spec } = {}) { | |
const z = new Zone({ | |
name, | |
spec: { | |
...spec, | |
...this.#spec, | |
}, | |
}); | |
return z; | |
} | |
get parent() { | |
return zones.get(this.#resource.triggerAsyncId()); | |
} | |
static get current() { | |
return zones.get(executionAsyncId()); | |
} | |
[util.inspect.custom](depth, options) { | |
const O = Object.assign({}, options, { | |
depth: options.depth === null ? null : options.depth - 1, | |
}); | |
return `Zone { | |
name => ${util.inspect(this.name, O)} | |
spec => ${util.inspect(this.#spec, O)} }`; | |
} | |
} | |
Zone.prototype[Symbol.toStringTag] = 'Zone'; | |
zones.set(executionAsyncId(), new Zone()); | |
createHook({ | |
init: (asyncId, type, triggerAsyncId) => { | |
zones.set(asyncId, zones.get(triggerAsyncId)); | |
}, | |
destroy: (asyncId) => { | |
zones.delete(asyncId); | |
}, | |
}).enable(); | |
global.Zone = Zone; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how do you give some use examples