From dabe5bfbae10de983bd1cbdba38949f17a62562e Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 10 Sep 2018 10:26:45 +0200 Subject: [FIX] web: ajax must return a promise with abort method Remove part in service_mixins who hide this error. Queries must be able to be canceled for better performance. Also in the case of longpolling, if the request is not canceled, wait for a server message or the maximum time (30 sec) to add or delete channels. --- addons/web/static/src/js/core/ajax.js | 2 +- addons/web/static/src/js/core/service_mixins.js | 10 +++++++-- addons/web/static/src/js/core/session.js | 9 ++++++-- addons/web/static/src/js/services/ajax_service.js | 25 +++++++++++++---------- 4 files changed, 30 insertions(+), 16 deletions(-) (limited to 'addons/web/static/src') diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js index fa79c65ef45..036af275f4e 100644 --- a/addons/web/static/src/js/core/ajax.js +++ b/addons/web/static/src/js/core/ajax.js @@ -38,7 +38,7 @@ function genericJsonRpc (fct_name, params, settings, fct) { }); // FIXME: jsonp? deferred.abort = function () { - deferred.reject('communication', $.Event(), 'abort', 'abort'); + deferred.reject({message: "XmlHttpRequestError abort"}, $.Event('abort')); if (xhr.abort) { xhr.abort(); } diff --git a/addons/web/static/src/js/core/service_mixins.js b/addons/web/static/src/js/core/service_mixins.js index 463b0aef4b1..7ca691cb2ad 100644 --- a/addons/web/static/src/js/core/service_mixins.js +++ b/addons/web/static/src/js/core/service_mixins.js @@ -125,8 +125,14 @@ var ServicesMixin = { */ _rpc: function (params, options) { var query = rpc.buildQuery(params); - var def = this.call('ajax', 'rpc', query.route, query.params, options); - return def ? def.promise() : $.Deferred().promise(); + var def = this.call('ajax', 'rpc', query.route, query.params, options, this); + if (!def && this.isDestroyed()) { + def = $.Deferred(); + def.abort = function () {}; + } + var promise = def.promise(); + promise.abort = def.abort.bind(def); + return promise; }, loadFieldView: function (dataset, view_id, view_type, options) { return this.loadViews(dataset.model, dataset.get_context().eval(), [[view_id, view_type]], options).then(function (result) { diff --git a/addons/web/static/src/js/core/session.js b/addons/web/static/src/js/core/session.js index 09b65357404..694285cccdc 100644 --- a/addons/web/static/src/js/core/session.js +++ b/addons/web/static/src/js/core/session.js @@ -344,9 +344,11 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { } }; - return deferred.then(function () { + var promise = deferred.then(function () { if (aborted) { - return $.Deferred().reject('communication', $.Event(), 'abort', 'abort'); + var def = $.Deferred().reject({message: "XmlHttpRequestError abort"}, $.Event('abort')); + def.abort = function () {}; + return def; } // TODO: remove if (! _.isString(url)) { @@ -374,6 +376,9 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { xhrDef = fct(url, "call", params, options); return xhrDef; }); + + promise.abort = deferred.abort; + return promise; }, url: function (path, params) { params = _.extend(params || {}); diff --git a/addons/web/static/src/js/services/ajax_service.js b/addons/web/static/src/js/services/ajax_service.js index 3446f651a59..6c61fdbf9ed 100644 --- a/addons/web/static/src/js/services/ajax_service.js +++ b/addons/web/static/src/js/services/ajax_service.js @@ -8,17 +8,20 @@ var session = require('web.session'); var AjaxService = AbstractService.extend({ name: 'ajax', rpc: function (route, args, options, target) { - return $.Deferred(function (def) { - session.rpc(route, args, options).then(function () { - if (!target.isDestroyed()) { - def.resolve.apply(def, arguments); - } - }, function () { - if (!target.isDestroyed()) { - def.reject.apply(def, arguments); - } - }); - }).promise(); + var def = $.Deferred(); + var promise = def.promise(); + var xhrDef = session.rpc(route, args, options); + promise.abort = xhrDef.abort.bind(xhrDef); + xhrDef.then(function () { + if (!target.isDestroyed()) { + def.resolve.apply(def, arguments); + } + }).fail(function () { + if (!target.isDestroyed()) { + def.reject.apply(def, arguments); + } + }); + return promise; }, }); -- cgit v1.2.3