Javascript Promise.then()在第一次单击按钮时不起作用

Javascript Promise.then()在第一次单击按钮时不起作用,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,我的问题是,当我在第一次加载页面时单击NewQuoteButton时,我得到一个错误:quoteGenerator.getQuote…然后不是一个函数。但是,如果我再次单击按钮,我可以正常生成引号。在Chrome inspector中查看我的网络选项卡时,我注意到我有更多来自API的get请求和响应,而我正在显示的报价却落后了 我是一个新的承诺,目前正在实践利用它以及揭示模块模式。我的理解是,一个允诺调用一个函数,该函数以该已解析允诺的值作为参数。因此,我的getQuote应该可以工作,因为它返

我的问题是,当我在第一次加载页面时单击NewQuoteButton时,我得到一个错误:quoteGenerator.getQuote…然后不是一个函数。但是,如果我再次单击按钮,我可以正常生成引号。在Chrome inspector中查看我的网络选项卡时,我注意到我有更多来自API的get请求和响应,而我正在显示的报价却落后了

我是一个新的承诺,目前正在实践利用它以及揭示模块模式。我的理解是,一个允诺调用一个函数,该函数以该已解析允诺的值作为参数。因此,我的getQuote应该可以工作,因为它返回一个包含quote对象的承诺。有人能给我指一下正确的方向吗。谢谢

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();
返回承诺链中的数据,如

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
        }; 
       });  
  };
返回承诺链中的数据,如

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
        }; 
       });  
  };

您需要返回fetch调用

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

使用单引号-它们更容易阅读

依我看,Promise catch块通常比使用err backs要干净一点

对错误使用真实的错误对象,而不仅仅是消息,否则将很难跟踪。您不需要新关键字,只需调用Error即可


您需要返回fetch调用

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

使用单引号-它们更容易阅读

依我看,Promise catch块通常比使用err backs要干净一点

对错误使用真实的错误对象,而不仅仅是消息,否则将很难跟踪。您不需要新关键字,只需调用Error即可



getQuote返回quoteInfo。第一次调用它时,承诺尚未完成,因此quoteInfo仍然是初始化为的空{}对象。我在回答中添加了一些建议。getQuote返回quoteInfo。第一次调用它时承诺尚未完成,因此quoteInfo仍然是初始化为的空{}对象。我在回答中添加了一些建议。您的quoteGenerator函数为空,因此quoteGenerator.getQuote将给出一个错误。这修复了它!谢谢我可以问一下为什么我的代码不起作用吗。我的理解是,我的函数返回一个承诺,然后我调用它来打印报价信息。@Justin是nnnnnn在注释中指出的、fetch未返回、value未从中返回的组合。然后,请参见;在承诺链之外的代码,试图将变量强制转换为异步procedure@nnnnnn第一个代码块中的函数只是为了说明IIFE模式不是必需的。不,如果它没有改变,我不会包含所有的代码,但我会在此处添加类似//其他代码的注释,以使其更清楚地显示其组合方式。您的quoteGenerator函数为空,因此quoteGenerator.getQuote将给出一个错误。这修复了它!谢谢我可以问一下为什么我的代码不起作用吗。我的理解是,我的函数返回一个承诺,然后我调用它来打印报价信息。@Justin是nnnnnn在注释中指出的、fetch未返回、value未从中返回的组合。然后,请参见;在承诺链之外的代码,试图将变量强制转换为异步procedure@nnnnnn第一个代码块中的函数只是为了说明IIFE模式不是必需的。不,如果它没有改变,我不会包含所有的代码,但我会在这里添加一条注释,类似//其他代码,保持不变,以便更清楚地说明它是如何结合在一起的。正如你所说,第2点是一个意见问题,讽刺的是,你没有遵守第3点……哈哈,没错,但英语与代码不同……你的编辑器可能会为你突出显示字符串,不管是单引号还是双引号。节省你自己的空间,空间?我以单间距字体编辑代码,因此单引号和双引号占用相同的空间。是的,我知道英语不同于代码,这是我过去说过的一点,我只是在开玩笑。哈哈,是的,我实际上忘了在捕获块中称“承诺拒绝”,正如你所说,固定点2是一个意见问题,讽刺的是,你没有遵守第3点……哈哈,真的,但是英语不同于代码…你的编辑器可能会为你突出显示字符串,wh
它是单引号或双引号。节省你自己的空间,空间?我以单间距字体编辑代码,因此单引号和双引号占用相同的空间。是的,我知道英语不同于代码,这是我过去说过的一点,我只是在开玩笑。哈哈,是的,我实际上忘了在catch块中调用promise-reject,修正了吗