返回一个 Promise,但得到“无法读取未定义的 属性 'then'”
Returning a Promise, but getting 'Cannot read property 'then' of undefined'
我已经阅读了其他人在这里遇到此错误的示例,但在尝试将 promises 链接在一起时我仍然遇到同样的错误。
在下面的代码中,pegasus(基于 promise 的 http 库:https://github.com/typicode/pegasus)调用 API,返回一些 JSON,然后 returns 一个承诺。我可以使用第一个 then
毫无问题地处理它 returns 返回的数据。这段代码是同步的,最初我没有返回一个承诺,因为我的印象是它没有必要(而且可能仍然没有必要)。在下面的代码中,我尝试将它包装在一个 promise 中,因为这是 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));
});
知道我可能哪里出错了吗?
问题是 pegasus
没有实现 A+/Promises。或者,实际上,generally-accepted 意义上的任何类型的承诺。
如果我们查看它的 source code,我们可以看到它的 then
函数没有 return 任何东西:
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
在 Promises 意义上,return 是 XHR 对象。
适当的 then
函数 return 是一个新的承诺。 pegasus
函数及其 then
return 根本不是一个承诺。
@Brideau 对此感到抱歉,then
可能令人困惑。作为@T.J。解释说,这不是真正的 Promise。我将在 README
.
中强调该部分
关于不使用 Promises,Pegasus 的想法是它加载得越快,它就可以越快地开始发出请求。
这就是我不使用 Promise polyfill 的原因。这是为了使图书馆尽可能小。出于同样的原因,我也只支持 GET
+ JSON
请求。
关于 "weird" 代码风格,我正在使用
Byte-saving Techniques。这就是为什么,例如,函数参数被用作变量占位符。
所以一开始应该使用 Pegasus,但之后您可以使用其他库来发出更复杂的请求。
我希望它能让事情变得更清楚:)
我已经阅读了其他人在这里遇到此错误的示例,但在尝试将 promises 链接在一起时我仍然遇到同样的错误。
在下面的代码中,pegasus(基于 promise 的 http 库:https://github.com/typicode/pegasus)调用 API,返回一些 JSON,然后 returns 一个承诺。我可以使用第一个 then
毫无问题地处理它 returns 返回的数据。这段代码是同步的,最初我没有返回一个承诺,因为我的印象是它没有必要(而且可能仍然没有必要)。在下面的代码中,我尝试将它包装在一个 promise 中,因为这是 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));
});
知道我可能哪里出错了吗?
问题是 pegasus
没有实现 A+/Promises。或者,实际上,generally-accepted 意义上的任何类型的承诺。
如果我们查看它的 source code,我们可以看到它的 then
函数没有 return 任何东西:
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
在 Promises 意义上,return 是 XHR 对象。
适当的 then
函数 return 是一个新的承诺。 pegasus
函数及其 then
return 根本不是一个承诺。
@Brideau 对此感到抱歉,then
可能令人困惑。作为@T.J。解释说,这不是真正的 Promise。我将在 README
.
关于不使用 Promises,Pegasus 的想法是它加载得越快,它就可以越快地开始发出请求。
这就是我不使用 Promise polyfill 的原因。这是为了使图书馆尽可能小。出于同样的原因,我也只支持 GET
+ JSON
请求。
关于 "weird" 代码风格,我正在使用 Byte-saving Techniques。这就是为什么,例如,函数参数被用作变量占位符。
所以一开始应该使用 Pegasus,但之后您可以使用其他库来发出更复杂的请求。
我希望它能让事情变得更清楚:)