--- /dev/null
+"use strict";\r
+module.exports = asPromise;\r
+\r
+/**\r
+ * Callback as used by {@link util.asPromise}.\r
+ * @typedef asPromiseCallback\r
+ * @type {function}\r
+ * @param {Error|null} error Error, if any\r
+ * @param {...*} params Additional arguments\r
+ * @returns {undefined}\r
+ */\r
+\r
+/**\r
+ * Returns a promise from a node-style callback function.\r
+ * @memberof util\r
+ * @param {asPromiseCallback} fn Function to call\r
+ * @param {*} ctx Function context\r
+ * @param {...*} params Function arguments\r
+ * @returns {Promise<*>} Promisified function\r
+ */\r
+function asPromise(fn, ctx/*, varargs */) {\r
+ var params = new Array(arguments.length - 1),\r
+ offset = 0,\r
+ index = 2,\r
+ pending = true;\r
+ while (index < arguments.length)\r
+ params[offset++] = arguments[index++];\r
+ return new Promise(function executor(resolve, reject) {\r
+ params[offset] = function callback(err/*, varargs */) {\r
+ if (pending) {\r
+ pending = false;\r
+ if (err)\r
+ reject(err);\r
+ else {\r
+ var params = new Array(arguments.length - 1),\r
+ offset = 0;\r
+ while (offset < params.length)\r
+ params[offset++] = arguments[offset];\r
+ resolve.apply(null, params);\r
+ }\r
+ }\r
+ };\r
+ try {\r
+ fn.apply(ctx || null, params);\r
+ } catch (err) {\r
+ if (pending) {\r
+ pending = false;\r
+ reject(err);\r
+ }\r
+ }\r
+ });\r
+}\r