Skip to content

Commit

Permalink
Add implementation for keys.settle
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonyvia committed Jul 30, 2015
1 parent 3e05cb7 commit e73b1fb
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
16 changes: 16 additions & 0 deletions docs/api.md
Expand Up @@ -44,6 +44,7 @@ API
* when/keys
* [keys.all(object)](#whenkeys-all)
* [keys.map(object, mapper)](#whenkeys-map)
* [keys.settle(object)](#whenkeys-settle)
1. Functions
* when/function
* [fn.lift(f)](#fnlift)
Expand Down Expand Up @@ -920,6 +921,7 @@ settled.then(function(descriptors) {
### See also:
* [when.all](#whenall)
* [promise.inspect](#inspect)
* [keys.settle](#whenkeys-settle)

# Objects

Expand Down Expand Up @@ -970,6 +972,20 @@ Where:
### See also:
* [when.map](#whenmap)

## when/keys settle

```js
var promise = keys.settle(object)
```

Where
* object is an Object whose keys represent promises and/or values.

Similar to `when.settle`, but for object keys, returns a promise for the key-value pairs with a resultant descriptor object for each key. The returned promise should always fulfill.

### See also:
* [when.settle](#whensettle)

# Array Races

The *competitive race* pattern may be used if one or more of the entire possible set of *eventual outcomes* are sufficient to resolve a promise.
Expand Down
35 changes: 34 additions & 1 deletion keys.js
Expand Up @@ -16,7 +16,8 @@ define(function(require) {

return {
all: when.lift(all),
map: map
map: map,
settle: settle
};

/**
Expand Down Expand Up @@ -76,5 +77,37 @@ define(function(require) {
}
}

/**
* Resolve all key-value pairs in the supplied object and return a promise
* that will always fulfill with the outcome states of all input promises.
* @param {object} object whose key-value pairs will be settled
* @returns {Promise} promise for an object with the mapped and fully
* settled key-value pairs
*/
function settle(object) {
var p = Promise._defer();
var resolver = Promise._handler(p);

var results = {};
var keys = Object.keys(object);
var promises = keys.map(function(k) { return object[k]; });
var pending = keys.length;

when.settle(promises).then(function(d) {
for(var i=0; i<keys.length; i++) {
results[keys[i]] = d[i];
if(--pending === 0) {
resolver.resolve(results);
}
}
});

if(pending === 0) {
resolver.resolve(results);
}

return p;
}

});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
57 changes: 57 additions & 0 deletions test/keys-test.js
Expand Up @@ -174,5 +174,62 @@ buster.testCase('when/keys', {
}
).ensure(done);
}
},

'settle': {
'should resolve empty input': function() {
return keys.settle({}).then(assertNoKeys);
},

'should resolve promise for keys': function(done) {
var input = { a:1, b:2, c:3 };
return keys.settle(input).then(
function(results) {
assert.equals(
results,
{
a: { state: 'fulfilled', value: 1 },
b: { state: 'fulfilled', value: 2 },
c: { state: 'fulfilled', value: 3 }
}
);
},
fail
).ensure(done);
},

'should resolve promised keys': function(done) {
var input = { a: resolve(1), b: 2, c: resolve(3) };
keys.settle(input).then(
function(results) {
assert.equals(
results,
{
a: { state: 'fulfilled', value: 1 },
b: { state: 'fulfilled', value: 2 },
c: { state: 'fulfilled', value: 3 }
}
);
},
fail
).ensure(done);
},

'should not reject if key rejects': function(done) {
var input = { a: 1, b: reject('reason'), c: 3 };
keys.settle(input).then(
function(results) {
assert.equals(
results,
{
a: { state: 'fulfilled', value: 1 },
b: { state: 'rejected', reason: 'reason' },
c: { state: 'fulfilled', value: 3 }
}
);
},
fail
).ensure(done);
}
}
});

0 comments on commit e73b1fb

Please sign in to comment.