我遇到的问题是当我点击" NewQuoteButton"在第一次加载页面时,我收到错误:quoteGenerator.getQuote(...).then is not a function
。但是,如果我再次点击该按钮,我就能正常生成报价。此外,在检查我的Chrome检查器中的网络选项卡时,我注意到我有更多来自API的请求和响应,而我正在显示的报价滞后。
我是Promises的新手,目前正在练习利用它以及揭示模块模式。我的理解是Promise调用then(),它接受一个函数,将已解析的promise的值作为参数。因此,我的getQuote()应该工作,因为它返回一个包含引用对象的Promise。有人能指出我正确的方向。谢谢!
const quoteGenerator = (function(){
let url = "https://andruxnet-random-famous-quotes.p.mashape.com/?cat=famous";
let apiHeader = new Headers({
"X-Mashape-Key": "..."
});
let init = {
headers : apiHeader,
}
let quoteInfo = {};
let getQuote = function(){
fetch(url, init)
.then(response => {
if (response.ok){
return response.json();
}
throw new Error("Get request failed");
}, networkError => console.log("Error: " + networkError))
.then(jsonResponse => {
quoteInfo = Promise.resolve({
quote: jsonResponse.quote,
author: jsonResponse.author
});
});
return quoteInfo;
};
return {
getQuote : getQuote
};
})();
//Triggers when user clicks on social media button to share quote.
//Checks to see if quote has been generated from quoteGenerator before
//sharing it, if not, then button does nothing.
const clickHandler = (function(){
let triggerClicked = function(){
$("#twitter").on("click", function(e){
e.preventDefault();
window.open("https://twitter.com/intent/tweet?text=asdf");
});
$("#newQuoteButton").on("click", function(e){
//ERROR BELOW//
quoteGenerator.getQuote().then(function(quoteInfo){
//ERROR ABOVE//
$("#quoteSection > h2").html("<i class='fa fa-quote-left'></i>" +
quoteInfo.quote + "<i class='fa fa-quote-right'></i>");
$("#author").html("<i>- " + quoteInfo.author + "</i>");
}).catch(function(e){
console.log(e);
});
});
};
return {
handleClicks: triggerClicked
}
})();
clickHandler.handleClicks();
答案 0 :(得分:4)
返回Promise
链中的数据,并按照@nnnnnn
getQuote()
返回quoteInfo
。它第一次被称为 承诺尚未完成,因此quoteInfo
仍为空{}
对象它被初始化为。
quoteInfo
可以从代码中省略
let getQuote = function() {
return fetch(url, init)
.then(response => {
if (response.ok){
return response.json();
}
throw new Error("Get request failed");
}, networkError => console.log("Error: " + networkError))
.then(jsonResponse => {
return {
quote: jsonResponse.quote,
author: jsonResponse.author
};
});
};
$("#newQuoteButton").on("click", function(e){
//ERROR BELOW//
quoteGenerator.getQuote().then(function(quoteInfo){
//ERROR ABOVE//
$("#quoteSection > h2")
.html("<i class='fa fa-quote-left'></i>"
+ quoteInfo.quote + "<i class='fa fa-quote-right'></i>");
$("#author").html("<i>- " + quoteInfo.author + "</i>");
}).catch(function(e){
console.log(e);
});
});
答案 1 :(得分:2)
您需要返回提取呼叫
let getQuote = function(){
return fetch(url, init) // <<<<<<< use 'return'
.then(resp => {
return resp.ok ? resp.json() : Promise.reject(Error('Get request failed'));
})
.catch(networkError => {
console.error('Error: ' + networkError);
return Promise.reject(networkError); // <<<< have to call reject here, or throw
})
.then(jsonResponse => {
return {
quote: jsonResponse.quote,
author: jsonResponse.author
};
});
};
动态输入FTW:)
4个提示:
使用console.error而不是console.log来处理错误,因为这会写入stderr而不是stdout
使用单引号 - 它们更容易阅读IMO
Promise catch块通常比使用“err-backs”更清洁,IMO
为您的错误使用真正的错误对象,而不仅仅是消息,否则将难以追踪。您不需要new关键字,只需调用Error()。