Skip to content

Commit

Permalink
timeout (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlaziuk authored Jan 28, 2018
1 parent c7bb21a commit 92b3d84
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 5 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ There is already a few libraries with similar functionality, yet this is another
``` typescript
import asap from "asap-es";
import delay from "asap-es/delay";
import timeout from "asap-es/timeout";

// you can have many independent queues
const queue = new asap();

// promises
queue.q(() => Promise.resolve(2)).then(console.log);
// console >> 2

// async functions
queue.q(async () => {
// do some async things
});
Expand All @@ -65,4 +69,14 @@ queue.q(() => {
throw new Error();
}).catch(console.error);
// console >> error

// timeout a task after given time
queue.q(timeout(200, () => {
// a long task
}));

// combine delay and timeout
queue.q(delay(10, timeout(5, () => {
// this task waits 10 ms for execution, then timeouts in 5 ms
})))
```
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"access": "public",
"name": "asap-es",
"version": "1.1.1",
"version": "1.2.0",
"description": "asap with promise support",
"main": "index",
"private": false,
Expand Down Expand Up @@ -31,11 +31,11 @@
},
"keywords": [
"asap",
"queue",
"task-queue",
"promise",
"async",
"asynchronous"
"asynchronous",
"promise",
"queue",
"task-queue"
],
"author": "Tomek Łaziuk <[email protected]>",
"license": "MIT",
Expand Down
80 changes: 80 additions & 0 deletions timeout.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
expect,
} from "chai";

import {
spy,
} from "sinon";

import ASAP from ".";
import delay from "./delay";
import timeout from "./timeout";

describe(timeout.name || "timeout", () => {
it("should return a 'function'", () => {
expect(timeout(0, () => void 0)).to.be.a("function");
});
it("should the task function be callled", async () => {
const taskSpy = spy();
const taskNew = timeout(0, taskSpy);
try {
await taskNew();
} catch {
// pass
}
expect(taskSpy.callCount).to.be.equal(1);
});
it("should the new task resolve to value of original task", async () => {
const task = () => "abc";
const taskNew = timeout(0, task);
expect(await taskNew()).to.be.equal("abc");
});
it("should the new task reject when execution time exceeds the timeout", (done) => {
const task = () => new Promise<void>(
(resolve, reject) => {
setTimeout(() => {
resolve();
}, 10);
},
);
const taskNew = timeout(0, task);
taskNew().catch(() => done());
});
it("should the waiting time for task not count into the task execution time", async () => {
const task = delay(10, (): string => "abc");
const taskNew = timeout(0, task);
expect(await taskNew()).to.be.equal("abc");
});
it("should rejection be instance of 'Error'", async () => {
const task = () => delay(10, "abc");
const taskNew = timeout(0, task);
let err;
try {
await taskNew();
} catch (e) {
err = e;
}
expect(err).to.be.instanceOf(Error);
});
it("should reject if task Promise rejects", (done) => {
const task = () => Promise.reject(new Error());
const taskNew = timeout(10, task);
taskNew().catch(() => done());
});
it("should be working in a queue", async () => {
const queue = new ASAP();
expect(await queue.q(timeout(10, () => delay(5, "abc")))).to.be.equal("abc");
});
it("should reject if task throws", async () => {
const task = () => { throw new Error("error"); };
const taskNew = timeout(10, task);
let err;
try {
await taskNew();
} catch (e) {
err = e;
}
expect(err).to.be.instanceOf(Error);
expect((err as Error).message).to.be.equal("error");
});
});
26 changes: 26 additions & 0 deletions timeout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { task } from ".";

/**
* reject when the execution exceeds given time
*
* @param timeout time in milliseconds
* @param fn task to run
*/
export default <T = any>(
timeout: number,
fn: task<T> | PromiseLike<task<T>>,
): (() => Promise<T>) => () => Promise.resolve(fn).then(
// run the logic when task will be ready
(taskFn) => new Promise<T>(
(resolve, reject) => {
Promise.resolve(
// task is ready, yet it may return a promise
taskFn(),
).then(resolve, reject);
setTimeout(() => {
// reject when the timeout is reached
reject(new Error());
}, timeout);
},
),
);

0 comments on commit 92b3d84

Please sign in to comment.