[英]Promise.then() doesn't work on first button click
The problem I have is that when I click on the "NewQuoteButton" on the FIRST time the page loads, I get an error: quoteGenerator.getQuote(...).then is not a function
. 我的问题是,当我第一次在页面加载时单击“ NewQuoteButton”时,出现错误:
quoteGenerator.getQuote(...).then is not a function
。 However, if I click the button again, I'm able to generate the quotes normally. 但是,如果再次单击该按钮,则可以正常生成报价。 Also upon examining my network tab in Chrome inspector, I noticed I had a lot more get requests and responses from the API while my quote that is being displayed is lagging behind.
另外,在Chrome检查器中检查“网络”标签后,我注意到我收到的来自API的请求和响应很多,而所显示的报价却落后了。
I'm new to Promises and currently practicing utilizing it along with revealing module pattern. 我是Promises的新手,目前正在练习与显示模块模式一起使用它。 My understanding is that a Promise calls then() which takes a function with that resolved promise's value as the argument.
我的理解是,一个Promise调用then(),该方法将一个函数以已解析的promise的值作为参数。 Therefore, my getQuote() should work because it returns a Promise containing a quote object.
因此,我的getQuote()应该可以工作,因为它返回一个包含引号对象的Promise。 Can someone point me in the right direction.
有人可以指出我正确的方向。 Thanks!
谢谢!
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();
Return the data within Promise
chain, and as pointed out by @nnnnnn 返回
Promise
链中的数据,并由@nnnnnn指出
getQuote()
returnsquoteInfo
.getQuote()
返回quoteInfo
。 The first time it is called the promise has not yet completed, soquoteInfo
is still the empty{}
object it was initialised as.第一次调用promise尚未完成,因此
quoteInfo
仍然是它初始化为的空{}
对象。
quoteInfo
can be omitted from the code 可以从代码中省略
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);
});
});
You need to return the fetch call 您需要返回提取调用
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
};
});
};
dynamic typing FTW :) 动态输入FTW :)
4 tips: 4个提示:
use console.error instead of console.log for errors since this writes to stderr not stdout 使用console.error而不是console.log进行错误,因为这会写入stderr而不是stdout
use single quotes - they are easier to read IMO 使用单引号-它们更易于阅读IMO
Promise catch blocks are usually a little cleaner than using "err-backs", IMO IMO承诺的捕获块通常比使用“错误返回”更干净
Use a real Error object for your errors, not just a message, otherwise will be difficult to track down. 对错误使用真实的Error对象,而不仅仅是消息,否则将难以跟踪。 You don't need the new keyword, just call Error().
您不需要new关键字,只需调用Error()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.