Skip to content

Commit

Permalink
Implement P.props
Browse files Browse the repository at this point in the history
  • Loading branch information
kjvalencik committed Jun 14, 2016
1 parent 9a05bc2 commit db4a3c3
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Additional examples are available in [tests](tests).
- [`method(Function method)`](#methodfunction-method)
- [`fromCallback(Function callback)`](#fromcallbackfunction-callback)
- [`defer(Function fn)`](#deferfunction-fn)
- [`props(Object obj)`](#propsobject-obj)
- [`extend(Promise)`](#extendpromise)
* [Instance Methods](#instance-methods)
- [`return(value)`](#returnvalue)
Expand Down Expand Up @@ -146,6 +147,35 @@ deferred.promise.catch(console.error);
deferred.reject(new Error("Goodbye, World!"));
```

#### `props(Object obj)`

Accepts an object and waits for all promise values to resolve before returning. Returns
a new object with values from the resolved promises.

```js
const P = require("extends-promise");

P
.props({
x : P.delay(100, 'a'),
y : P.delay(50, 'b'),
z : 'c'
})
.then(res => console.log(res.x));
```

This method can be especially helpful when combined with destructuring as a way of returning
named tuples.

```js
P
.props({
x : P.delay(100, 'a'),
y : 'b'
})
.then(({ x, y }) => console.log(`x: ${x}, y: ${y}`));
```

#### `extend(Promise)`

Extend a promise implementation with methods in this library. Useful if you want
Expand Down
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ class P extends Promise {
return p.forEach(fn);
}

static props(o) {
const keys = Object.keys(o);

return P
.map(keys, k => o[k])
.then(res => res.reduce((y, x, i) => Object.assign(y, {
[keys[i]] : x
}), {}));
}

static promisify(fn, ctx) {
return function promisifedMethod() {
return new P((resolve, reject) => {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "extends-promise",
"version": "1.3.0",
"version": "1.4.0",
"description": "Micro-library that extends native promises",
"main": "index.js",
"engines": {
Expand Down Expand Up @@ -30,11 +30,11 @@
"homepage": "https://github.com/kjvalencik/extends-promise#readme",
"devDependencies": {
"eslint-config-airbnb-base": "^3.0.1",
"eslint-plugin-import": "^1.8.0",
"eslint-plugin-import": "^1.9.0",
"gulp": "^3.9.1",
"gulp-coveralls": "^0.1.4",
"gulp-eslint": "^2.0.0",
"gulp-istanbul": "^0.10.4",
"gulp-istanbul": "^1.0.0",
"gulp-mocha": "^2.2.0"
}
}
30 changes: 28 additions & 2 deletions tests/helpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ describe("Helpers", () => {
});

describe(".tap", () => {
it(".tap: should be able to call then without affecting chain", () => {
it("should be able to call then without affecting chain", () => {
return P
.resolve(1)
.tap(() => 2)
.then(res => assert.strictEqual(res, 1));
});

it(".tap: should wait for returned promise to resolve", () => {
it("should wait for returned promise to resolve", () => {
let waited = false;

return P
Expand All @@ -105,4 +105,30 @@ describe("Helpers", () => {
.then(() => assert.strictEqual(waited, true));
});
});

describe(".props", () => {
it("should wait for promise values to reolve", () => {
return P
.props({
x : P.delay(1, 'a'),
y : P.delay(5, 'b')
})
.then(res => assert.deepEqual(res, {
x : 'a',
y : 'b'
}));
});

it("should allow non-promise keys", () => {
return P
.props({
x : P.delay(1, 'a'),
y : 'b'
})
.then(res => assert.deepEqual(res, {
x : 'a',
y : 'b'
}));
});
});
});

0 comments on commit db4a3c3

Please sign in to comment.