Promise中的这个上下文不引用内部实例

时间:2015-09-28 04:35:26

标签: javascript promise es6-promise

我不确定我期待的是否正确,但如果Promise与任何其他JavaScript类一样,那么它应该有this上下文。

但以下代码让我感到惊讶。

var promise = new Promise(function (resolve, reject) {
    console.log(this === window); // Prints true
});

我在这里错过了本机Promise的概念吗?

我的目标是在创建它时将一些属性附加到promise对象,并且以后能够访问它。

我知道Promise中传递的回调函数不在任何上下文中,并且就像普通函数一样被调用。但是有没有办法将属性附加到返回的每个承诺?

this.someProp = someobj.returnVal();

更多信息

基本上,我在promise中创建了一个ajax请求,并且我希望将请求对象存储在promise中,以便我可以在需要时将其用于abort请求。向abort

添加填充Promise.prototype

这是实际的代码。

var _request;

const promise = new Promise(function (resolve, reject) {

  this._request = superagent.get(url)
     .end((error, res) => { resolve(res); }); // What I expect to work 

  _request = superagent.get(url)
     .end((error, res) => { resolve(res); }); // But I have no this context
});

Promise.prototype.abort = function () {
  this._request.abort(); // Can't do this
}

1 个答案:

答案 0 :(得分:1)

您要求我发布的想法是返回一个包含请求对象和promise的对象,然后调用者可以使用其中任何一个:

function getInfo(url) {
    var req = superagent.get(url);
    var p = new Promise(function(resolve, reject) {
        req.end(function(error, res) { 
            if (error) return reject(error);
            resolve(res); 
        });
    });
    // return an object with both promise and request object in it
    // so caller can use either
    return {promise: p, req: req};
}

var ret = getInfo(myURL);
ret.promise.then(function(res) {
    // handle response here
}, function(err) {
    // handle error here
});

// you could also do this at any time
ret.req.abort();

事实证明,您可以使用相同的结构将请求对象放在这样的承诺上(虽然我不推荐它,因为链接承诺会创建新的承诺,从而丢失原始承诺上的自定义属性) :

function getInfo(url) {
    var req = superagent.get(url);
    var p = new Promise(function(resolve, reject) {
        req.end(function(error, res) { 
            if (error) return reject(error);
            resolve(res); 
        });
    });
    p.req = req;
    return p;
}

或者,您可以将promise放在请求对象上(这更安全):

function getInfo(url) {
    var req = superagent.get(url);
    var p = new Promise(function(resolve, reject) {
        req.end(function(error, res) { 
            if (error) return reject(error);
            resolve(res); 
        });
    });
    req.promise = p;
    return req;
}