rxjs-ajax-cancelable
Version:
Cancelable XMLHttpRequest library based on RxJS.
161 lines • 6.3 kB
JavaScript
;
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var Observable_1 = require("rxjs/Observable");
var Subject_1 = require("rxjs/Subject");
require("rxjs/add/observable/of");
require("rxjs/add/observable/dom/ajax");
require("rxjs/add/operator/take");
require("rxjs/add/operator/takeUntil");
require("rxjs/add/operator/map");
require("rxjs/add/operator/filter");
require("rxjs/add/operator/mergeMap");
require("rxjs/add/operator/switchMap");
require("rxjs/add/operator/exhaustMap");
// import 'rxjs/add/operator/timeout'
// import 'rxjs/add/operator/timeoutWith'
require("rxjs/add/operator/retry");
require("rxjs/add/operator/catch");
require("rxjs/add/operator/toPromise");
require("rxjs/add/operator/do");
require("rxjs/add/operator/share");
require("rxjs/add/operator/partition");
var DEFAULT_TIMEOUT = 1000 * 15;
var DEFAULT_RETRY = 2;
var TESTING = false;
var AjaxCancelable = (function () {
function AjaxCancelable(request) {
this.request = request;
this.refCount = 0;
}
AjaxCancelable.prototype.invokeSubjects = function () {
var _this = this;
if (!this.canceller$ || this.canceller$.isStopped || this.canceller$.closed) {
this.canceller$ = new Subject_1.Subject();
}
if (!this.subject$ || this.subject$.isStopped || this.subject$.closed) {
this.subject$ = new Subject_1.Subject();
var obs = this.subject$
.partition(function (ajaxObj) { return ajaxObj.priorityFirst; });
obs[0] // prioritize the first stream.
.exhaustMap(function (ajaxObj) { return _this.ajaxRequestCallback(ajaxObj); })
.subscribe({
next: function (ajaxObj) { return ajaxObj.responseSubject$.next(ajaxObj.response); },
error: function (err) { throw err; },
});
obs[1] // prioritize the last stream.
.switchMap(function (ajaxObj) { return _this.ajaxRequestCallback(ajaxObj); })
.subscribe({
next: function (ajaxObj) { return ajaxObj.responseSubject$.next(ajaxObj.response); },
error: function (err) { throw err; },
});
}
};
AjaxCancelable.prototype.requestAjax = function (request) {
var _this = this;
if (!this.request && !request) {
throw new Error('ERROR: AjaxRequest is undefined.');
}
this.refCount += 1;
this.invokeSubjects();
var _request = Object.assign({}, this.request, request); // merge request objects.
_request.timeout = _request.timeout || DEFAULT_TIMEOUT;
if (_request.testing) {
TESTING = true;
}
var responseSubject$ = new Subject_1.Subject();
var ajaxObj = {
request: _request,
response: null,
responseSubject$: responseSubject$,
retry: typeof _request.retry === 'number' && _request.retry >= 0 ? _request.retry : DEFAULT_RETRY,
priorityFirst: !!_request.priorityFirst,
};
this.subject$.next(ajaxObj);
var observable = responseSubject$
.take(1)
.takeUntil(this.canceller$)
.share();
observable
.subscribe({
complete: function () {
if (TESTING) {
console.log('responseSubject$ is completed.');
}
_this.refCount -= 1;
if (_this.refCount === 0) {
_this.unsubscribeSubjects();
if (TESTING) {
console.log('Ajax subjects are unsubscribed.');
}
}
}
});
return observable;
};
AjaxCancelable.prototype.requestAjaxAsPromise = function (request) {
return this.requestAjax(request).toPromise();
};
AjaxCancelable.prototype.requestPriorityLastAjax = function (request) {
var _request = __assign({}, request, { priorityFirst: false });
return this.requestAjax(_request);
};
AjaxCancelable.prototype.requestPriorityLastAjaxAsPromise = function (request) {
return this.requestPriorityLastAjax(request).toPromise();
};
AjaxCancelable.prototype.requestPriorityFirstAjax = function (request) {
var _request = __assign({}, request, { priorityFirst: true });
return this.requestAjax(_request);
};
AjaxCancelable.prototype.requestPriorityFirstAjaxAsPromise = function (request) {
return this.requestPriorityFirstAjax(request).toPromise();
};
AjaxCancelable.prototype.cancelAjax = function () {
console.log('Ajax cancel signal is sent.');
this.canceller$.next();
};
AjaxCancelable.prototype.unsubscribeSubjects = function () {
if (this.subject$) {
this.subject$.unsubscribe();
}
if (this.canceller$) {
this.canceller$.unsubscribe();
}
};
AjaxCancelable.prototype.ajaxRequestCallback = function (ajaxObj) {
var startTime = new Date().getTime();
return Observable_1.Observable.ajax(ajaxObj.request)
.retry(ajaxObj.retry)
.catch(function (err, caught) {
if (err) {
if (!TESTING) {
console.error({
status: err.status,
message: err.message,
url: err.request.url,
response: err.response,
});
}
return Observable_1.Observable.of(err);
}
else {
return caught;
}
})
.take(1)
.takeUntil(this.canceller$)
.map(function (data) {
ajaxObj.response = __assign({}, data, { processingTime: new Date().getTime() - startTime });
return ajaxObj;
});
};
return AjaxCancelable;
}());
exports.AjaxCancelable = AjaxCancelable;
//# sourceMappingURL=ajax-cancelable.js.map