diff --git a/lib/check.js b/lib/check.js index d73adea..804588a 100644 --- a/lib/check.js +++ b/lib/check.js @@ -1,44 +1,37 @@ module.exports = check -var Promise = require('lie') - var internals = module.exports.internals = {} -internals.nets = require('nets') internals.cache = require('./utils/cache') +internals.request = require('./utils/request') function check (state) { - return new Promise(function (resolve, reject) { - internals.nets({ - method: state.method, - url: state.url, - timeout: state.timeout - }, function (error, response, body) { - state.timestamp = new Date().toISOString() - - if (error) { - error.name = error.code === 'ETIMEDOUT' ? 'TimeoutError' : 'ConnectionError' - error.code = undefined - handleError(state, error) - return reject(error) - } - - if (response.statusCode >= 400) { - error = new Error('Server error') - error.name = 'ServerError' - error.code = response.statusCode - handleError(state, error) - return reject(error) - } - - if (state.error) { - state.emitter.emit('reconnect') - delete state.error - } - - internals.cache.set(state) - - resolve() - }) + if (state.request) { + state.request.abort() + } + + state.request = internals.request({ + method: state.method, + url: state.url, + timeout: state.timeout + }) + + // once requet finishes, remove it from state + state.request.catch(function (error) { + delete state.request + state.timestamp = new Date().toISOString() + handleError(state, error) + }) + + return state.request.then(function () { + delete state.request + state.timestamp = new Date().toISOString() + + if (state.error) { + state.emitter.emit('reconnect') + delete state.error + } + + internals.cache.set(state) }) } diff --git a/lib/reset.js b/lib/reset.js index 4d7766a..b3b181a 100644 --- a/lib/reset.js +++ b/lib/reset.js @@ -7,6 +7,11 @@ function reset (state) { state.timestamp = undefined state.error = undefined cache.set(state) + + if (state.request) { + state.request.abort() + } + return Promise.resolve().then(function () { state.emitter.emit('reset') }) diff --git a/lib/utils/request.js b/lib/utils/request.js new file mode 100644 index 0000000..167468d --- /dev/null +++ b/lib/utils/request.js @@ -0,0 +1,44 @@ +module.exports = request + +var nets = require('nets') +var Promise = require('lie') + +function request (options) { + var requestState + var reject + var promise = new Promise(function (resolve, _reject) { + reject = _reject + requestState = nets({ + method: options.method, + url: options.url, + timeout: options.timeout + }, function (error, response, body) { + if (error) { + error.name = error.code === 'ETIMEDOUT' ? 'TimeoutError' : 'ConnectionError' + error.code = undefined + return reject(error) + } + + if (response.statusCode >= 400) { + error = new Error('Server error') + error.name = 'ServerError' + error.code = response.statusCode + return reject(error) + } + + resolve() + }) + }) + + promise.abort = function () { + try { + requestState.abort() + } catch (error) {} + var error = new Error('Aborted') + error.name = 'AbortError' + error.code = 0 + reject(error) + } + + return promise +}