在调用this._super之前如何捕获承诺?使用Javascript

时间:2014-10-08 08:43:13

标签: javascript ajax asynchronous promise odoo

我想从我的请求“instance.web.Model”获得结果,然后调用this.super()。问题是“instance.web.Model”是异步的,所以在我的情况下,super()将在请求完成之前被调用。

MyObject.extend({

    init: function(parent, data){

        var newData = instance.web.Model('advanced.search')
        .call('check_duplication', [data]).done(function (name) {
            // do stuff
            return name
        });

        data = newData;
        this._super.apply(this, arguments);
        // super is called before my request is done so the new data are not sent to super.

    }
});

你知道如何度过难关吗?为了将newData而不是数据作为参数传递给超级对象。

PS:我试图将其封装在自我中:var self = this;但它不起作用,因为我似乎扩展的父对象继续运行而不等待。所以我得到了像“self.super(......不是函数)”这样的错误。

MyObject.extend({

    init: function(parent, data){
        var self = this;

        var newData = instance.web.Model('advanced.search')
        .call('check_duplication', [data]).done(function (name) {
            // do stuff
            var newData = name;
            self._super.apply(self, parent, newData);
            // or self._super.apply(self, arguments); etc... I tried many variantes
        });

    }
});

回答Bergi,因为他问我_super()正在调用什么。 instance.web.Model在服务器端调用python脚本,我想这是一种Ajax调用。但我测试了很多情况,我假设这个instance.web.Model调用是异步的。这就是我扩展的对象:

instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
events: {
    'change .searchview_extended_prop_field': 'changed',
    'change .searchview_extended_prop_op': 'operator_changed',
    'click .searchview_extended_delete_prop': function (e) {
        e.stopPropagation();
        this.getParent().remove_proposition(this);
    }
},
/**
 * @constructs instance.web.search.ExtendedSearchProposition
 * @extends instance.web.Widget
 *
 * @param parent
 * @param fields
 */
init: function (parent, fields) {
    this._super(parent);
    this.fields = _(fields).chain()
        .map(function(val, key) { return _.extend({}, val, {'name': key}); })
        .filter(function (field) { return !field.deprecated && (field.store === void 0 || field.store || field.fnct_search); })
        .sortBy(function(field) {return field.string;})
        .value();
    this.attrs = {_: _, fields: this.fields, selected: null};
    this.value = null;
},

更进一步(希望它能帮到你)。好的,让我们看看谁是超类:

instance.web.Widget = instance.web.Controller.extend({
// Backbone-ish API
tagName: 'div',
id: null,
className: null,
attributes: {},
events: {},
/**
 * The name of the QWeb template that will be used for rendering. Must be
 * redefined in subclasses or the default render() method can not be used.
 *
 * @type string
 */
template: null,
/**
 * Constructs the widget and sets its parent if a parent is given.
 *
 * @constructs instance.web.Widget
 *
 * @param {instance.web.Widget} parent Binds the current instance to the given Widget instance.
 * When that widget is destroyed by calling destroy(), the current instance will be
 * destroyed too. Can be null.
 */
init: function(parent) {
    this._super(parent);
    // Bind on_/do_* methods to this
    // We might remove this automatic binding in the future
    for (var name in this) {
        if(typeof(this[name]) == "function") {
            if((/^on_|^do_/).test(name)) {
                this[name] = this[name].bind(this);
            }
        }
    }
    // FIXME: this should not be
    this.setElement(this._make_descriptive());
    this.session = instance.session;
},

然后,下一个:

instance.web.Controller = instance.web.Class.extend(instance.web.PropertiesMixin, {
/**
 * Constructs the object and sets its parent if a parent is given.
 *
 * @param {instance.web.Controller} parent Binds the current instance to the given Controller instance.
 * When that controller is destroyed by calling destroy(), the current instance will be
 * destroyed too. Can be null.
 */
init: function(parent) {
    instance.web.PropertiesMixin.init.call(this);
    this.setParent(parent);
},

然后:

instance.web.PropertiesMixin = _.extend({}, instance.web.EventDispatcherMixin, {
init: function() {
    instance.web.EventDispatcherMixin.init.call(this);
    this.__getterSetterInternalMap = {};
},

然后:

instance.web.EventDispatcherMixin = _.extend({}, instance.web.ParentedMixin, {
__eventDispatcherMixin: true,
init: function() {
    instance.web.ParentedMixin.init.call(this);
    this.__edispatcherEvents = new Events();
    this.__edispatcherRegisteredEvents = [];
},

最后:

instance.web.ParentedMixin = {
__parentedMixin : true,
init: function() {
    this.__parentedDestroyed = false;
    this.__parentedChildren = [];
    this.__parentedParent = null;
},

1 个答案:

答案 0 :(得分:1)

我不认为大多数框架提供的动态super方法确实异步工作 - 但是如果你使用promises,它确实需要(promises总是异步的)。

因此,如果您需要从promise回调中调用父级的初始化方法,您可以尝试

MyObject.extend({
    init: function(parent, data){
        var _super = this._super.bind(this);

        instance.web.Model('advanced.search')
        .call('check_duplication', [data])
        .done(function (name) {
            _super(parent, name);
        });
        // or in short, even just:
        // .done(this._super.bind(this, parent));
    }
});

或者根本不使用_super native capability来引用您的父类:

MyObject.extend({
    init: function(parent, data){
        var self = this;

        instance.web.Model('advanced.search')
        .call('check_duplication', [data])
        .done(function (name) {
            instance.web.search.ExtendedSearchProposition.prototype.init // or whatever the parent method is
              .call(self, parent, newData);
        });
    }
});