@@ -1055,3 +1055,53 @@ process.versions[exports.inspect.custom] =
1055
1055
( depth ) => exports . format ( JSON . parse ( JSON . stringify ( process . versions ) ) ) ;
1056
1056
1057
1057
exports . promisify = internalUtil . promisify ;
1058
+
1059
+ function callbackifyOnRejected ( reason , cb ) {
1060
+ // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
1061
+ // Because `null` is a special error value in callbacks which means "no error
1062
+ // occurred", we error-wrap so the callback consumer can distinguish between
1063
+ // "the promise rejected with null" or "the promise fulfilled with undefined".
1064
+ if ( ! reason ) {
1065
+ const newReason = new errors . Error ( 'FALSY_VALUE_REJECTION' ) ;
1066
+ newReason . reason = reason ;
1067
+ reason = newReason ;
1068
+ Error . captureStackTrace ( reason , callbackifyOnRejected ) ;
1069
+ }
1070
+ return cb ( reason ) ;
1071
+ }
1072
+
1073
+
1074
+ function callbackify ( original ) {
1075
+ if ( typeof original !== 'function' ) {
1076
+ throw new errors . TypeError (
1077
+ 'ERR_INVALID_ARG_TYPE' ,
1078
+ 'original' ,
1079
+ 'function' ) ;
1080
+ }
1081
+
1082
+ // We DO NOT return the promise as it gives the user a false sense that
1083
+ // the promise is actually somehow related to the callback's execution
1084
+ // and that the callback throwing will reject the promise.
1085
+ function callbackified ( ...args ) {
1086
+ const maybeCb = args . pop ( ) ;
1087
+ if ( typeof maybeCb !== 'function' ) {
1088
+ throw new errors . TypeError (
1089
+ 'ERR_INVALID_ARG_TYPE' ,
1090
+ 'last argument' ,
1091
+ 'function' ) ;
1092
+ }
1093
+ const cb = ( ...args ) => { Reflect . apply ( maybeCb , this , args ) ; } ;
1094
+ // In true node style we process the callback on `nextTick` with all the
1095
+ // implications (stack, `uncaughtException`, `async_hooks`)
1096
+ Reflect . apply ( original , this , args )
1097
+ . then ( ( ret ) => process . nextTick ( cb , null , ret ) ,
1098
+ ( rej ) => process . nextTick ( callbackifyOnRejected , rej , cb ) ) ;
1099
+ }
1100
+
1101
+ Object . setPrototypeOf ( callbackified , Object . getPrototypeOf ( original ) ) ;
1102
+ Object . defineProperties ( callbackified ,
1103
+ Object . getOwnPropertyDescriptors ( original ) ) ;
1104
+ return callbackified ;
1105
+ }
1106
+
1107
+ exports . callbackify = callbackify ;
0 commit comments