使用Q - 如何调用对象的异步函数来更新对象属性

时间:2013-10-15 01:31:15

标签: node.js q

我正在使用NodeJS的Q promises,而我的代码没有按预期工作。

我有一个ObjA类型的数组。每个ObjA都有一个ObjB类型的属性objB。 ObjB有一个名为extract的异步方法,它执行异步任务并设置/更新objB属性。我在异步函数中使用Q.defer并返回延迟的promise。

我将延迟的承诺添加到数组并调用Q.all。 此部分按预期工作,并调用objB.exract(我已通过console.log验证)。

但是当我随后输出结果时,objB属性没有改变(即使我在提取中设置它们)。

以下是代码:

//file ObjA.js

exports.ObjA = function(data)
{
this._id = data.id;
this._created_at = data.created_at;
this._objB = new ObjB.ObjB(data.somefield);
};

//file ObjB.js

exports.ObjB = function(data)
{
    this._afield = data;
    this._bfield = '';
    this._cfield = '';
};

exports.ObjB.prototype.extract = function()
{
    var deferred = Q.defer();
    async_call(this._afield, function(e, resp)
    {
        if (e)
        {
            console.log(e);
            return deferred.reject(e);
        }
        else
        {
            this._bfield = resp.val1;
            this._cfield = resp.val2;
            console.log(this._bfield + ", " + this._cfield);
            return deferred.resolve(resp);
        }
     };
    return deferred.promise;
};

//main file,

var alist = [];
// code to populate alist with objects of type ObjA
var queue = [];
for (var i=0; i<alist.length; i++)
{
    queue.push(alist[i]._objB.extract());
}

Q.all(queue).then(function(succ)
    {
        console.log('final values');
        console.log(alist);
    },
      function(err)
    {
        console.log(err)
    }
    );

运行此操作时,会正确调用数据提取,this._bfieldthis._cfieldconsole.log正确输出。 但接下来是Q.all()的成功函数,它会输出'最终值',然后是'objB._bfieldobjB._cfield

为什么提取中设置的值没有打印?我猜这与对象引用有关,但无法确定这里有什么问题。

非常感谢任何帮助。

感谢

1 个答案:

答案 0 :(得分:0)

关注'this'关键字,替换这段代码:

async_call(this._afield, function(e, resp)
{
    if (e)
    {
        console.log(e);
        return deferred.reject(e);
    }
    else
    {
        this._bfield = resp.val1;
        this._cfield = resp.val2;
        console.log(this._bfield + ", " + this._cfield);
        return deferred.resolve(resp);
    }
 };

为:

var that = this;
async_call(this._afield, function(e, resp){
    if (e)
    {
        console.log(e);
        deferred.reject(e);
    }
    else
    {
        that._bfield = resp.val1;
        that._cfield = resp.val2;
        console.log(that._bfield + ", " + that._cfield);
        deferred.resolve(resp);
    }
 });