Skip to content

Commit

Permalink
P.try and P.method
Browse files Browse the repository at this point in the history
  • Loading branch information
kjvalencik committed May 21, 2016
1 parent a49b7dc commit 523e6c6
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,41 @@ Optionally, you can choose a suffix to append instead of "Async". Choosing an em
}
```

#### `try(Function method)`

Similar to a synchronous `try {}` block but, for promises. The result of `P.try` will always be a promise even if the method returned or threw synchronously.

```js
P
.try(() => {
const r = Math.floor(Math.random() * 5);

switch (r) {
case 0: return 0;
case 1: return P.resolve(1);
default: throw new Error("Something bad happened!");
}
})
.then(console.log)
.catch(console.error);
```

#### `method(Function method)`

Creates a method from the provided function that will always return a promise. Similar to `P.try`, but returns a method instead of invoking one. It will also accept arguments and maintain the `this` context.

```js
const Calc = {
add : P.method(function add(x, y) {
return x + y;
})
};

Calc
.add(1, 2)
.then(console.log);
```

#### `fromCallback(Function callback)`

Ad-hoc conversion from a callback to a promise. Also, useful for promisifying
Expand Down
14 changes: 14 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ class P extends Promise {
}), obj);
}

static try(fn) {
try {
return P.resolve(fn());
} catch (err) {
return P.reject(err);
}
}

static method(fn) {
return function promisifedMethod() {
return P.try(() => fn.apply(this, arguments));
};
}

static fromCallback(fn) {
return P.promisify(fn)();
}
Expand Down
74 changes: 74 additions & 0 deletions tests/promise.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,80 @@ describe("Promise", () => {
});
});

describe(".try", () => {
it("should return a promise from a synchronous function", () => {
return P
.try(() => "test")
.then(res => assert.strictEqual(res, "test"));
});

it("should return a rejected promise on synchronous exception", () => {
const fnErr = new Error("Test error");

return P
.try(() => {
throw fnErr;
})
.then(() => P.reject(new Error("Did not reject")))
.catch(err => assert.strictEqual(err, fnErr));
});

it("should wait for a resolved promise", () => {
return P
.try(() => P.resolve("test"))
.then(res => assert.strictEqual(res, "test"));
});

it("should wait for a rejected promise", () => {
const fnErr = new Error("Test error");

return P
.try(() => P.reject(fnErr))
.then(() => P.reject(new Error("Did not reject")))
.catch(err => assert.strictEqual(err, fnErr));
});
});

describe(".method", () => {
it("should return a method that returns a promise from a synchronous function", () => {
return P
.method(() => "test")()
.then(res => assert.strictEqual(res, "test"));
});

it("should return a rejected promise on synchronous exception", () => {
const fnErr = new Error("Test error");

return P
.method(() => {
throw fnErr;
})()
.then(() => P.reject(new Error("Did not reject")))
.catch(err => assert.strictEqual(err, fnErr));
});

it("should pass arguments to promisified function", () => {
return P
.method((a, b, c) => [a, b, c])(1, 2, 3)
.then(res => assert.deepEqual(res, [1, 2, 3]));
});

it("should pass `this` context to promisified function", () => {
const o = {
fn() {
return this;
}
};

return Object
.assign(o, {
fn : P.method(o.fn)
})
.fn()
.then(res => assert.strictEqual(res, o));
});
});

describe(".fromCallback", () => {
it("should be able to use fromCallback to promisify", () => {
return P
Expand Down

0 comments on commit 523e6c6

Please sign in to comment.