蓝鸟承诺范围

时间:2014-09-12 14:32:54

标签: javascript promise bluebird

我刚开始使用promises试图清理一些回调地狱'。

我决定尝试蓝鸟,我在浏览器中运行它但是立即遇到了范围问题。

有没有办法在新Promise中设置thisArg?以下示例显示了' this' promise解析器中的值设置为浏览器窗口,但我希望它设置为周围的范围,以便我可以轻松访问成员变量。

我注意到有一个.bind()方法,但它只限制了'然后()'方法,而不是承诺。我也意识到我可以拥有' var me = this'就在承诺和使用封闭之前,但我想尽可能避免它。

function MyObject() {
    this.value = 7;
}

MyObject.prototype.getValue = function () {
    return new Promise(function (resolve) {
        // some request/processing that takes a long time
        var result = Ajax.request(...);

        resolve({
            value: this.value,
            result: result
        });
        // 'this' is set to window instead of the instance,
        // resulting in this.value as undefined
    });
}

var obj = new MyObject();
obj.getValue().then(function (value) {
    console.log(value); // preferably outputs 7
})

2 个答案:

答案 0 :(得分:2)

不,没有。你当然可以use the default approaches,但你不应该这样做。

在进行大量处理并异步获取值时,您希望获得值的值。您不需要将结果值设置为原始实例的属性。

MyObject.prototype.getValue = function () {
    return new Promise(function(resolve) {
        // lots of processing to make a `value`
        resolve(value); // no `this` at all!
    });
};

如果您想同步获取在实例上设置的.value,则不需要Promise构造函数。只需使用Promise.resolve为现有值做出承诺:

MyObject.prototype.getValue = function () {
    // TODO: lots of processing
    return Promise.resolve(this.value);
};

或者,在您的情况下,甚至是Promise.method

// TODO: lots of processing
MyObject.prototype.getValue = Promise.method(function () {
    return this.value;
});

答案 1 :(得分:2)

这是一个评论,然后是一个答案,因为它是基于主要意见。

在我需要它的rar情况下,在我的代码中看起来像这样:

在这种情况下,

Ajax.requestAsync将是Ajax.request的宣传版。

我知道这可能只是将你的问题转移到另一个地方。

MyObject.prototype.getValue = function () {
    return Ajax.requestAsync(...)
    .bind(this)
    .then(function(result) {
        return {
              value: this.value,
              result: result
            }
    });
}

或类似的东西:

 MyObject.prototype.getValue = function () {
    var returnValue = {
        value: this.value
    };

    return Ajax.requestAsync(...)
    .then(function(result) {
        returnValue.result = result;
        return returnValue;
    });
}

很少使用这样的结构:

MyObject.prototype.getValue = function () {
  return Promise.all([this, Ajax.requestAsync(...)])
  .spread(function(object, result) {
      return {
        value: object.value,
        result: result
      };
  });
}