Promise
,用于查找链接的最终重定向URL。我的做法是使用
XMLHttpRequest
在Promise
中进行HEAD
请求。然后,在加载时,检查HTTP状态是否在300范围内,或者如果对象附加了responseURL
并且该URL与原始URL不同。如果以上两个条件都不成立,我会使用
resolve(url)
。否则,我会在响应URL上递归调用getRedirectUrl()
和resolve()
。以下是我的代码:
function getRedirectUrl(url, maxRedirects) {
maxRedirects = maxRedirects || 0;
if (maxRedirects > 10) {
throw new Error("Redirected too many times.");
}
var xhr = new XMLHttpRequest();
var p = new Promise(function (resolve) {
xhr.onload = function () {
var redirectsTo;
if (this.status < 400 && this.status >= 300) {
redirectsTo = this.getResponseHeader("Location");
} else if (this.responseURL && this.responseURL != url) {
redirectsTo = this.responseURL;
}
if (redirectsTo) {
// check that redirect address doesn't redirect again
// **problem line**
p.then(function () { self.getRedirectUrl(redirectsTo, maxRedirects + 1); });
resolve();
} else {
resolve(url);
}
}
xhr.open('HEAD', url, true);
xhr.send();
});
return p;
}
然后使用这个函数的方法如下:
getRedirectUrl(myUrl).then(function (url) { ... });
问题在于
getRedirectUrl
中的resolve();
会在调用函数的then()
之前调用,而在此时,URL是undefined
。我尝试过使用
return self.getRedirectUrl(...)
代替p.then(...getRedirectUrl...)
,但这永远不会解决问题。我猜测我使用的模式(基本上是临时想出来的)不太对。
p.then(...)
与一个不产生任何可观察副作用且不返回任何值的函数一起使用是没有意义的。 - zerkmsthen()
的常规链和多个函数变得更加明显。 - Evert