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

View file

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

View file

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

View file

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

View file

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