我不确定我所期望的是否正确,但如果 Promise
就像任何其他 JavaScript 类一样,它应该有一个 this
上下文。
但是下面的代码让我感到惊讶。
var promise = new Promise(function (resolve, reject) {
console.log(this === window); // Prints true
});
我在这里错过了原生 Promise 的概念吗?
我的目标是在创建 Promise 对象时将一些属性附加到它,并稍后能够访问它。
我知道在 Promise
中传递的回调函数不在任何上下文中,并且会像普通函数一样被调用。但是有没有办法将属性附加到每个返回的 promise 上?
this.someProp = someobj.returnVal();
更多信息
基本上,我在 Promise 中发出 Ajax 请求,并且我想将请求对象存储在 Promise 中,以便我可以在需要时使用它来中止
请求。通过添加一个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
}
最佳答案
这是您要求我发布的想法,它返回一个包含请求对象和 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();
事实证明,您可以使用相同的结构将请求对象放在这样的 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;
}
或者,您可以将 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;
}
关于javascript - Promise 中的 this 上下文并不引用内部实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32815748/