keys.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /** @license MIT License (c) copyright 2011-2013 original author or authors */
  2. /**
  3. * Licensed under the MIT License at:
  4. * http://www.opensource.org/licenses/mit-license.php
  5. *
  6. * @author Brian Cavalier
  7. * @author John Hann
  8. */
  9. (function(define) { 'use strict';
  10. define(function(require) {
  11. var when = require('./when');
  12. var Promise = when.Promise;
  13. var toPromise = when.resolve;
  14. return {
  15. all: when.lift(all),
  16. map: map,
  17. settle: settle
  18. };
  19. /**
  20. * Resolve all the key-value pairs in the supplied object or promise
  21. * for an object.
  22. * @param {Promise|object} object or promise for object whose key-value pairs
  23. * will be resolved
  24. * @returns {Promise} promise for an object with the fully resolved key-value pairs
  25. */
  26. function all(object) {
  27. var p = Promise._defer();
  28. var resolver = Promise._handler(p);
  29. var results = {};
  30. var keys = Object.keys(object);
  31. var pending = keys.length;
  32. for(var i=0, k; i<keys.length; ++i) {
  33. k = keys[i];
  34. Promise._handler(object[k]).fold(settleKey, k, results, resolver);
  35. }
  36. if(pending === 0) {
  37. resolver.resolve(results);
  38. }
  39. return p;
  40. function settleKey(k, x, resolver) {
  41. /*jshint validthis:true*/
  42. this[k] = x;
  43. if(--pending === 0) {
  44. resolver.resolve(results);
  45. }
  46. }
  47. }
  48. /**
  49. * Map values in the supplied object's keys
  50. * @param {Promise|object} object or promise for object whose key-value pairs
  51. * will be reduced
  52. * @param {function(value:*, key:String):*} f mapping function which may
  53. * return either a promise or a value
  54. * @returns {Promise} promise for an object with the mapped and fully
  55. * resolved key-value pairs
  56. */
  57. function map(object, f) {
  58. return toPromise(object).then(function(object) {
  59. return all(Object.keys(object).reduce(function(o, k) {
  60. o[k] = toPromise(object[k]).fold(mapWithKey, k);
  61. return o;
  62. }, {}));
  63. });
  64. function mapWithKey(k, x) {
  65. return f(x, k);
  66. }
  67. }
  68. /**
  69. * Resolve all key-value pairs in the supplied object and return a promise
  70. * that will always fulfill with the outcome states of all input promises.
  71. * @param {object} object whose key-value pairs will be settled
  72. * @returns {Promise} promise for an object with the mapped and fully
  73. * settled key-value pairs
  74. */
  75. function settle(object) {
  76. var keys = Object.keys(object);
  77. var results = {};
  78. if(keys.length === 0) {
  79. return toPromise(results);
  80. }
  81. var p = Promise._defer();
  82. var resolver = Promise._handler(p);
  83. var promises = keys.map(function(k) { return object[k]; });
  84. when.settle(promises).then(function(states) {
  85. populateResults(keys, states, results, resolver);
  86. });
  87. return p;
  88. }
  89. function populateResults(keys, states, results, resolver) {
  90. for(var i=0; i<keys.length; i++) {
  91. results[keys[i]] = states[i];
  92. }
  93. resolver.resolve(results);
  94. }
  95. });
  96. })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });