Skip to content

Commit

Permalink
Add timeout option (#4)
Browse files Browse the repository at this point in the history
Co-authored-by: Luke Batchelor <[email protected]>
  • Loading branch information
2 people authored and sindresorhus committed Jul 29, 2018
1 parent a112539 commit c2093ce
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: node_js
node_js:
- '8'
- '6'
- '4'
46 changes: 30 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
'use strict';
module.exports = (condition, interval) => new Promise((resolve, reject) => {
interval = typeof interval === 'number' ? interval : 20;
const pTimeout = require('p-timeout');

const check = () => {
Promise.resolve().then(condition).then(val => {
if (typeof val !== 'boolean') {
throw new TypeError('Expected condition to return a boolean');
}
module.exports = (condition, opts) => {
opts = Object.assign({
interval: 20,
timeout: Infinity
}, opts);
const promise = new Promise((resolve, reject) => {
const check = () => {
Promise.resolve().then(condition).then(val => {
if (typeof val !== 'boolean') {
throw new TypeError('Expected condition to return a boolean');
}

if (val === true) {
resolve();
} else {
setTimeout(check, interval);
}
}).catch(reject);
};
if (val === true) {
resolve();
} else {
setTimeout(check, opts.interval);
}
}).catch(err => {
reject(err);
});
};

check();
});
check();
});

if (opts.timeout !== Infinity) {
return pTimeout(promise, opts.timeout);
}

return promise;
};
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,8 @@
},
"xo": {
"esnext": true
},
"dependencies": {
"p-timeout": "^2.0.1"
}
}
15 changes: 12 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pWaitFor(() => pathExists('unicorn.png')).then(() => {

## API

### pWaitFor(condition, [interval])
### pWaitFor(condition, [options])

Returns a `Promise` that resolves when `condition` returns `true`. Rejects if `condition` throws or returns a `Promise` that rejects.

Expand All @@ -36,12 +36,21 @@ Type: `Function`

Expected to return a `boolean` or a `Promise` for a `boolean`.

#### interval
#### options

##### interval

Type: `number`<br>
Default: `20`

Number of milliseconds to wait before retrying `condition`.
Number of milliseconds to wait before retrying `condition`. You can also pass a number in place of the options object to set the interval.

##### timeout

Type: `number`<br>
Default: `Infinity`

Number of milliseconds to wait before automatically rejecting.


## Related
Expand Down
12 changes: 11 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava';
import delay from 'delay';
import timeSpan from 'time-span';
import m from './';
import m from '.';

const fixture = Symbol('unicorn');

Expand All @@ -16,3 +16,13 @@ test('waits for condition', async t => {
test('rejects promise if condition rejects or throws', async t => {
await t.throws(m(() => Promise.reject(new Error('foo'))));
});

test('Will wait not longer than `timeout`ms before rejecting', async t => {
const end = timeSpan();
const ms = 200;
const maxWait = 100;
await t.throws(m(() => delay(ms).then(() => true), {interval: 20, timeout: maxWait}));
const timeTaken = end();
t.true(timeTaken < ms);
t.true(timeTaken > (maxWait - 20));
});

0 comments on commit c2093ce

Please sign in to comment.