我已经阅读了其他人在此处收到此错误的示例,但在尝试将承诺链接在一起时,我仍然会遇到同样的错误。
在下面的代码中,pegasus(基于promise的http库:https://github.com/typicode/pegasus)调用API,获取一些JSON,并返回一个promise。我可以使用第一个then
处理它返回的数据而不会出现问题。这段代码是同步的,最初我没有回复承诺,因为我的印象是它不是必要的(而且可能不是)。在下面的代码中,我尝试将其包装在一个承诺中,因为这是Stack Overflow上其他类似问题的常用解决方案,但这似乎也没有解决它。
但是,我收到了TypeError: Cannot read property 'then' of undefined
消息。
var polygonGeo, centroidGeo;
var hexData = pegasus(hexUrl)
.then(function(data, xhr) {
return new Promise(function(resolve, reject) {
var features = data.features;
var polygons = features.filter(function(feature) {
return feature.properties.kind === 'Hexagon';
});
var centroids = features.filter(function(feature) {
return feature.properties.kind === 'Centroid';
});
polygonGeo = $.extend(true, {}, data);
centroidGeo = $.extend(true, {}, data);
polygonGeo.features = polygons;
centroidGeo.features = centroids;
if (typeof polygonGeo !== 'undefined' &&
typeof centroidGeo !== 'undefined') {
resolve();
}
});
}).then(function() {
console.log('It never reaches here.');
}).catch(function(error) {
console.log(Error(error));
});
知道我可能会出错吗?
答案 0 :(得分:1)
问题是pegasus
没有实现A + / Promises。或者,实际上,在普遍接受的意义上的任何承诺。
如果我们查看其source code,我们可以看到其then
函数没有返回任何内容:
function pegasus(a, xhr) {
xhr = new XMLHttpRequest();
// ...lines omitted...
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, data) {
// ...lines omitted, there is no `return` anywhere, at all...
};
// Send
xhr.send();
// Return request
return xhr;
}
它正在创建一个XHR对象,然后向它添加一个then
属性,这个函数是没什么奇怪的而不是一个正确的then
in Promise感觉到,并返回XHR对象。
正确的then
函数会返回一个新的承诺。 pegasus
函数及其then
都没有返回承诺。
答案 1 :(得分:1)
@Brideau对不起,then
可能会让人感到困惑。作为@ T.J。解释说,这不是一个真正的承诺。我将在README
中强调这一部分。
关于不使用Promise,Pegasus的想法是它加载的速度越快,开始发出请求的速度就越快。
这就是为什么我没有使用Promise polyfill。这是为了使图书馆尽可能小。我出于同样的原因,我也只支持GET
+ JSON
个请求。
关于“怪异”的代码风格,我正在使用 Byte-saving Techniques。这就是为什么,例如,函数参数被用作变量占位符。
所以Pegasus应该在开始时使用,但之后你可以使用其他库来提出更复杂的请求。
我希望它能让事情变得更加清晰:)