【问题标题】:this context inside Promise doesn't refer to the internal instancePromise 中的 this 上下文不引用内部实例
【发布时间】:2015-12-25 06:25:23
【问题描述】:

我不确定我的期望是否正确,但如果 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 请求。通过将 polyfill 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
}

【问题讨论】:

  • 你能描述一下是什么问题让你想在承诺中附加一些东西,因为可能有更好的方法来解决你的问题。
  • @jfriend00 jqXHR - 这不是假设 jquery 吗? fetch developer.mozilla.org/en/docs/Web/API/Fetch_API 可能是答案(IE 有一个 polyfill)
  • 是的,我的错。我以为是jQuery。请显示您的实际代码。也许您需要返回一个同时包含 Promise 和 XHR 对象的对象,而不仅仅是一个 Promise。
  • 请贴出代码。如果我们可以看到您尝试使用的实际代码,而不是尝试回答通常与您尝试遵循的解决方案有关的抽象问题,而不是对实际整体问题的描述,那么您总是会得到更高质量的答案。
  • @JaromandaX - fetch() 是否返回带有 abort 方法的承诺? OP 希望能够对 ajax 调用使用 Promise,但也能够调用 abort()

标签: javascript promise es6-promise


【解决方案1】:

这是你让我发布的想法,它返回一个包含请求对象和承诺的对象,然后调用者可以使用其中任何一个:

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

事实证明,您可以使用相同的结构将请求对象放在这样的 Promise 上(尽管我不推荐这样做,因为链接 Promise 会创建新的 Promise,从而丢失原始 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); 
        });
    });
    p.req = req;
    return p;
}

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

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

【讨论】:

  • 我喜欢req.promise = p; 的方法。让我看看我是否可以使用它。
猜你喜欢
  • 1970-01-01
  • 2015-04-24
  • 2018-06-27
  • 1970-01-01
  • 2018-06-02
  • 2020-01-17
  • 1970-01-01
  • 2017-06-17
  • 2011-12-28
相关资源
最近更新 更多