* Converts a Promise-returning function to callback style * @param {Function} original * @returns {Function}
(original)
| 399 | * @returns {Function} |
| 400 | */ |
| 401 | function callbackify(original) { |
| 402 | validateFunction(original, 'original'); |
| 403 | |
| 404 | // We DO NOT return the promise as it gives the user a false sense that |
| 405 | // the promise is actually somehow related to the callback's execution |
| 406 | // and that the callback throwing will reject the promise. |
| 407 | function callbackified(...args) { |
| 408 | const maybeCb = ArrayPrototypePop(args); |
| 409 | validateFunction(maybeCb, 'last argument'); |
| 410 | const cb = FunctionPrototypeBind(maybeCb, this); |
| 411 | // In true node style we process the callback on `nextTick` with all the |
| 412 | // implications (stack, `uncaughtException`, `async_hooks`) |
| 413 | ReflectApply(original, this, args) |
| 414 | .then((ret) => process.nextTick(cb, null, ret), |
| 415 | (rej) => process.nextTick(callbackifyOnRejected, rej, cb)); |
| 416 | } |
| 417 | |
| 418 | const descriptors = ObjectGetOwnPropertyDescriptors(original); |
| 419 | // It is possible to manipulate a functions `length` or `name` property. This |
| 420 | // guards against the manipulation. |
| 421 | if (typeof descriptors.length.value === 'number') { |
| 422 | descriptors.length.value++; |
| 423 | } |
| 424 | if (typeof descriptors.name.value === 'string') { |
| 425 | descriptors.name.value += 'Callbackified'; |
| 426 | } |
| 427 | const propertiesValues = ObjectValues(descriptors); |
| 428 | for (let i = 0; i < propertiesValues.length; i++) { |
| 429 | // We want to use null-prototype objects to not rely on globally mutable |
| 430 | // %Object.prototype%. |
| 431 | ObjectSetPrototypeOf(propertiesValues[i], null); |
| 432 | } |
| 433 | ObjectDefineProperties(callbackified, descriptors); |
| 434 | return callbackified; |
| 435 | } |
| 436 | |
| 437 | /** |
| 438 | * @param {number} err |
no outgoing calls
no test coverage detected
searching dependent graphs…