如何在打电话之前抓住承诺?Javascript

如何在打电话之前抓住承诺?Javascript,javascript,ajax,asynchronous,promise,odoo,Javascript,Ajax,Asynchronous,Promise,Odoo,我想从我的请求“instance.web.Model”中得到结果,然后调用这个.super()。问题是“instance.web.Model”是异步的,因此在我的例子中,将在请求完成之前调用super() MyObject.extend({ init: function(parent, data){ var newData = instance.web.Model('advanced.search') .call('check_duplication'

我想从我的请求“instance.web.Model”中得到结果,然后调用这个.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而不是data作为参数传递给超级对象

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

为了回答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.ParentedMixin = {
__parentedMixin : true,
init: function() {
    this.__parentedDestroyed = false;
    this.__parentedChildren = [];
    this.__parentedParent = null;
},

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

因此,如果需要从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));
    }
});
或者根本不要使用
\u super
来引用父类:

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);
        });
    }
});

\u super
在哪里定义?如果它是由您的框架隐式创建的(您使用哪一个?),它很可能无法异步工作。我注意到父级将其称为\u super()同样,这可能是我的问题之一。我很抱歉没有更明确地说明我的信息,我在这个领域的经验并不是很大,所以我不知道从哪里获得正确的信息来告诉你我想知道什么是
MyModel
,以及它是如何得到
extend
方法的?你可能在使用主干网吗?是的,有ome Backbone.js使用,但我不知道确切的位置。实际上我使用:instance.web.search.ExtendedSearchProposition.include({…而不是MyObject.extend)({…那么你说
instance.web.search.ExtendedSearchProposition
是你的超类,你想通过
super
调用
init
?我刚刚尝试了你的想法:第一个A->SyntaxError:super是一个保留标识符第一个B->类型错误:self.super不是一个函数第二个->类型错误:dict.widget。attrs是未定义的+无限递归自传递。done()作用域是problematicOops,第一个是我犯的愚蠢错误;第二个需要适应实际的超类(显然
MyObject
不是超类):)thx但是还有一个问题,比如案例2->TypeError:dict.widget.attrs没有定义。关于jQuery BlockUI插件呢?我听说它在我的程序中使用过。我不知道dict.widget.attrs是什么或者应该是什么。是的,它很复杂,因为有数千行JS代码。我以为我是从我的重写中构思出来的,但似乎有点棘手^^
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));
    }
});
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);
        });
    }
});