node-extensions.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. 'use strict';
  2. //This file contains then/promise specific extensions that are only useful for node.js interop
  3. var Promise = require('./core.js')
  4. var asap = require('asap')
  5. module.exports = Promise
  6. /* Static Functions */
  7. Promise.denodeify = function (fn, argumentCount) {
  8. argumentCount = argumentCount || Infinity
  9. return function () {
  10. var self = this
  11. var args = Array.prototype.slice.call(arguments)
  12. return new Promise(function (resolve, reject) {
  13. while (args.length && args.length > argumentCount) {
  14. args.pop()
  15. }
  16. args.push(function (err, res) {
  17. if (err) reject(err)
  18. else resolve(res)
  19. })
  20. var res = fn.apply(self, args)
  21. if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') {
  22. resolve(res)
  23. }
  24. })
  25. }
  26. }
  27. Promise.nodeify = function (fn) {
  28. return function () {
  29. var args = Array.prototype.slice.call(arguments)
  30. var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null
  31. var ctx = this
  32. try {
  33. return fn.apply(this, arguments).nodeify(callback, ctx)
  34. } catch (ex) {
  35. if (callback === null || typeof callback == 'undefined') {
  36. return new Promise(function (resolve, reject) { reject(ex) })
  37. } else {
  38. asap(function () {
  39. callback.call(ctx, ex)
  40. })
  41. }
  42. }
  43. }
  44. }
  45. Promise.prototype.nodeify = function (callback, ctx) {
  46. if (typeof callback != 'function') return this
  47. this.then(function (value) {
  48. asap(function () {
  49. callback.call(ctx, null, value)
  50. })
  51. }, function (err) {
  52. asap(function () {
  53. callback.call(ctx, err)
  54. })
  55. })
  56. }