Skip to content

Commit 27484f0

Browse files
committed
Implemented promises support
1 parent 2062358 commit 27484f0

File tree

1 file changed

+46
-15
lines changed

1 file changed

+46
-15
lines changed

index.js

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* MIT Licensed
88
*
99
*/
10+
var Promise = require('bluebird');
1011
var request = require('request');
1112
var _ = require('fg-lodash');
1213
var RetryStrategies = require('./strategies');
@@ -15,11 +16,13 @@ var RetryStrategies = require('./strategies');
1516
var DEFAULTS = {
1617
maxAttempts: 5, // try 5 times
1718
retryDelay: 5000, // wait for 5s before trying again
19+
fullResponse: true, // resolve promise with the full response object
1820
};
1921

20-
function Request(options, f, maxAttempts, retryDelay) {
21-
this.maxAttempts = maxAttempts;
22-
this.retryDelay = retryDelay;
22+
function Request(options, f, retryConfig) {
23+
this.maxAttempts = retryConfig.maxAttempts;
24+
this.retryDelay = retryConfig.retryDelay;
25+
this.fullResponse = retryConfig.fullResponse;
2326
this.attempts = 0;
2427

2528
/**
@@ -34,9 +37,32 @@ function Request(options, f, maxAttempts, retryDelay) {
3437
*/
3538
this.retryStrategy = _.isFunction(options.retryStrategy) ? options.retryStrategy : RetryStrategies.HTTPOrNetworkError;
3639

37-
this.f = _.once(f);
3840
this._timeout = null;
3941
this._req = null;
42+
43+
this._callback = _.isFunction(f) ? _.once(f) : null;
44+
45+
// create the promise only when no callback was provided
46+
if (!this._callback) {
47+
this._promise = new Promise(function (resolve, reject) {
48+
this._resolve = resolve;
49+
this._reject = reject;
50+
}.bind(this));
51+
}
52+
53+
this.reply = function requestRetryReply(err, response, body) {
54+
if (this._callback) {
55+
return this._callback(err, response, body);
56+
}
57+
58+
if (err) {
59+
return this._reject(err);
60+
}
61+
62+
// resolve with the full response or just the body
63+
response = this.fullResponse ? response : body;
64+
this._resolve(response);
65+
};
4066
}
4167

4268
Request.request = request;
@@ -54,7 +80,7 @@ Request.prototype._tryUntilFail = function () {
5480
return;
5581
}
5682

57-
return this.f(err, response, body);
83+
this.reply(err, response, body);
5884
}.bind(this));
5985
};
6086

@@ -63,24 +89,29 @@ Request.prototype.abort = function () {
6389
this._req.abort();
6490
}
6591
clearTimeout(this._timeout);
66-
this.f(new Error('Aborted'));
92+
this.reply(new Error('Aborted'));
6793
};
6894

6995
// expose request methods from RequestRetry
70-
['end', 'on', 'emit', 'once', 'setMaxListeners', 'start', 'removeListener', 'pipe', 'write'].forEach(function (methodName) {
71-
Request.prototype[methodName] = makeGateway(methodName);
96+
['end', 'on', 'emit', 'once', 'setMaxListeners', 'start', 'removeListener', 'pipe', 'write'].forEach(function (requestMethod) {
97+
Request.prototype[requestMethod] = function exposedRequestMethod () {
98+
return this._req[requestMethod].apply(this._req, arguments);
99+
};
72100
});
73101

74-
function makeGateway(methodName) {
75-
return function () {
76-
return this._req[methodName].apply(this._req, Array.prototype.slice.call(arguments));
102+
// expose promise methods
103+
['then', 'catch', 'finally'].forEach(function (promiseMethod) {
104+
Request.prototype[promiseMethod] = function exposedPromiseMethod () {
105+
if (this._callback) {
106+
throw new Error('A callback was provided but waiting a promise, use only one pattern');
107+
}
108+
return this._promise[promiseMethod].apply(this._promise, arguments);
77109
};
78-
}
110+
});
79111

80112
function Factory(options, f) {
81-
f = _.isFunction(f) ? f : _.noop;
82-
var retry = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
83-
var req = new Request(options, f, retry.maxAttempts, retry.retryDelay);
113+
var retryConfig = _(options || {}).defaults(DEFAULTS).pick(Object.keys(DEFAULTS)).value();
114+
var req = new Request(options, f, retryConfig);
84115
req._tryUntilFail();
85116
return req;
86117
}

0 commit comments

Comments
 (0)