You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

promisify.js 2.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. "use strict";
  2. /* global module, require */
  3. module.exports = function () {
  4. "use strict";
  5. // Get a promise object. This may be native, or it may be polyfilled
  6. var ES6Promise = require("./promise.js");
  7. /**
  8. * thatLooksLikeAPromiseToMe()
  9. *
  10. * Duck-types a promise.
  11. *
  12. * @param {object} o
  13. * @return {bool} True if this resembles a promise
  14. */
  15. function thatLooksLikeAPromiseToMe(o) {
  16. return o && typeof o.then === "function" && typeof o.catch === "function";
  17. }
  18. /**
  19. * promisify()
  20. *
  21. * Transforms callback-based function -- func(arg1, arg2 .. argN, callback) -- into
  22. * an ES6-compatible Promise. Promisify provides a default callback of the form (error, result)
  23. * and rejects when `error` is truthy. You can also supply settings object as the second argument.
  24. *
  25. * @param {function} original - The function to promisify
  26. * @param {object} settings - Settings object
  27. * @param {object} settings.thisArg - A `this` context to use. If not set, assume `settings` _is_ `thisArg`
  28. * @param {bool} settings.multiArgs - Should multiple arguments be returned as an array?
  29. * @return {function} A promisified version of `original`
  30. */
  31. return function promisify(original, settings) {
  32. return function () {
  33. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  34. args[_key] = arguments[_key];
  35. }
  36. var returnMultipleArguments = settings && settings.multiArgs;
  37. var target = void 0;
  38. if (settings && settings.thisArg) {
  39. target = settings.thisArg;
  40. } else if (settings) {
  41. target = settings;
  42. }
  43. // Return the promisified function
  44. return new ES6Promise(function (resolve, reject) {
  45. // Append the callback bound to the context
  46. args.push(function callback(err) {
  47. if (err) {
  48. return reject(err);
  49. }
  50. for (var _len2 = arguments.length, values = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  51. values[_key2 - 1] = arguments[_key2];
  52. }
  53. if (false === !!returnMultipleArguments) {
  54. return resolve(values[0]);
  55. }
  56. resolve(values);
  57. });
  58. // Call the function
  59. var response = original.apply(target, args);
  60. // If it looks like original already returns a promise,
  61. // then just resolve with that promise. Hopefully, the callback function we added will just be ignored.
  62. if (thatLooksLikeAPromiseToMe(response)) {
  63. resolve(response);
  64. }
  65. });
  66. };
  67. };
  68. }();