client/api: better promise aborting

This commit is contained in:
rr- 2017-01-07 16:24:56 +01:00
parent 8a73f7e400
commit beb8d8091b
5 changed files with 36 additions and 47 deletions

View File

@ -6,8 +6,6 @@ const request = require('superagent');
const config = require('./config.js'); const config = require('./config.js');
const events = require('./events.js'); const events = require('./events.js');
// TODO: fix abort misery
class Api extends events.EventTarget { class Api extends events.EventTarget {
constructor() { constructor() {
super(); super();
@ -149,8 +147,8 @@ class Api extends events.EventTarget {
// transform the request: upload each file, then make the request use // transform the request: upload each file, then make the request use
// its tokens. // its tokens.
data = Object.assign({}, data); data = Object.assign({}, data);
let promise = Promise.resolve();
let abortFunction = () => {}; let abortFunction = () => {};
let promise = Promise.resolve();
if (files) { if (files) {
for (let key of Object.keys(files)) { for (let key of Object.keys(files)) {
let file = files[key]; let file = files[key];
@ -159,9 +157,9 @@ class Api extends events.EventTarget {
} else { } else {
promise = promise promise = promise
.then(() => { .then(() => {
let returnedPromise = this._upload(file); let uploadPromise = this._upload(file);
abortFunction = () => { returnedPromise.abort(); }; abortFunction = () => uploadPromise.abort();
return returnedPromise; return uploadPromise;
}) })
.then(token => { .then(token => {
abortFunction = () => {}; abortFunction = () => {};
@ -172,9 +170,14 @@ class Api extends events.EventTarget {
} }
} }
} }
promise = promise.then(() => { promise = promise.then(
return this._rawRequest(url, requestFactory, data, {}, options); () => {
}, error => { let requestPromise = this._rawRequest(
url, requestFactory, data, {}, options);
abortFunction = () => requestPromise.abort();
return requestPromise;
},
error => {
// TODO: check if the error is because of expired uploads // TODO: check if the error is because of expired uploads
return Promise.reject(error); return Promise.reject(error);
}); });
@ -185,15 +188,14 @@ class Api extends events.EventTarget {
_upload(file, options) { _upload(file, options) {
let abortFunction = () => {}; let abortFunction = () => {};
let returnedPromise = new Promise((resolve, reject) => { let returnedPromise = new Promise((resolve, reject) => {
let apiPromise = this._rawRequest( let uploadPromise = this._rawRequest(
'/uploads', request.post, {}, {content: file}, options); '/uploads', request.post, {}, {content: file}, options);
abortFunction = () => apiPromise.abort(); abortFunction = () => uploadPromise.abort();
return apiPromise.then( return uploadPromise.then(
response => { response => {
resolve(response.token);
abortFunction = () => {}; abortFunction = () => {};
}, return resolve(response.token);
reject); }, reject);
}); });
returnedPromise.abort = () => abortFunction(); returnedPromise.abort = () => abortFunction();
return returnedPromise; return returnedPromise;
@ -204,9 +206,8 @@ class Api extends events.EventTarget {
data = Object.assign({}, data); data = Object.assign({}, data);
const [fullUrl, query] = this._getFullUrl(url); const [fullUrl, query] = this._getFullUrl(url);
let abortFunction = null; let abortFunction = () => {};
let returnedPromise = new Promise((resolve, reject) => {
let promise = new Promise((resolve, reject) => {
let req = requestFactory(fullUrl); let req = requestFactory(fullUrl);
req.set('Accept', 'application/json'); req.set('Accept', 'application/json');
@ -262,6 +263,7 @@ class Api extends events.EventTarget {
req.end((error, response) => { req.end((error, response) => {
nprogress.done(); nprogress.done();
abortFunction = () => {};
if (error) { if (error) {
if (response && response.body) { if (response && response.body) {
error = new Error( error = new Error(
@ -274,10 +276,8 @@ class Api extends events.EventTarget {
} }
}); });
}); });
returnedPromise.abort = () => abortFunction();
promise.abort = () => abortFunction(); return returnedPromise;
return promise;
} }
} }

View File

@ -115,19 +115,13 @@ class PostUploadController {
// no duplicates, proceed with saving // no duplicates, proceed with saving
let post = this._uploadableToPost(uploadable); let post = this._uploadableToPost(uploadable);
let apiSavePromise = post.save(uploadable.anonymous); let savePromise = post.save(uploadable.anonymous)
let returnedSavePromise = apiSavePromise
.then(() => { .then(() => {
this._view.removeUploadable(uploadable); this._view.removeUploadable(uploadable);
return Promise.resolve(); return Promise.resolve();
}); });
this._lastCancellablePromise = savePromise;
returnedSavePromise.abort = () => { return savePromise;
apiSavePromise.abort();
};
this._lastCancellablePromise = returnedSavePromise;
return returnedSavePromise;
}); });
} }

View File

@ -5,6 +5,8 @@ const misc = require('./util/misc.js');
const views = require('./util/views.js'); const views = require('./util/views.js');
const router = require('./router.js'); const router = require('./router.js');
Promise.prototype.abort = () => {};
history.scrollRestoration = 'manual'; history.scrollRestoration = 'manual';
router.exit( router.exit(

View File

@ -80,11 +80,7 @@ class Post extends events.EventTarget {
} }
return Promise.resolve(response); return Promise.resolve(response);
}); });
returnedPromise.abort = () => apiPromise.abort();
returnedPromise.abort = () => {
apiPromise.abort();
};
return returnedPromise; return returnedPromise;
} }
@ -156,7 +152,7 @@ class Post extends events.EventTarget {
api.put('/post/' + this._id, detail, files) : api.put('/post/' + this._id, detail, files) :
api.post('/posts', detail, files); api.post('/posts', detail, files);
let returnedPromise = apiPromise.then(response => { return apiPromise.then(response => {
this._updateFromResponse(response); this._updateFromResponse(response);
this.dispatchEvent( this.dispatchEvent(
new CustomEvent('change', {detail: {post: this}})); new CustomEvent('change', {detail: {post: this}}));
@ -177,12 +173,6 @@ class Post extends events.EventTarget {
} }
return Promise.reject(error); return Promise.reject(error);
}); });
returnedPromise.abort = () => {
apiPromise.abort();
};
return returnedPromise;
} }
feature() { feature() {

View File

@ -56,3 +56,6 @@ Number.prototype.between = function(a, b, inclusive) {
this >= min && this <= max : this >= min && this <= max :
this > min && this < max; this > min && this < max;
}; };
// non standard
Promise.prototype.abort = () => {};