如果Javascript长于x,则再次引用引号

时间:2017-05-01 17:25:04

标签: javascript

我有这个代码连接到API并从中绘制随机引用。

我想创建一个if语句来检查引号长度是低于还是等于140并返回它,或者如果它更长但是再次绘制,但我不知道如何开始。

request = new XMLHttpRequest();
request.open("GET", "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=20", false);
request.send(); 
request = [].slice.call(JSON.parse(request.response));

var button = document.getElementById("button");
var authorname = document.getElementById("authorname");
var quotetext = document.getElementById("quotetext");
var drawnquote = request[Math.floor(Math.random() * request.length)].content;

button.addEventListener("click", function() {
  quotetext.innerHTML = request[Math.floor(Math.random() * request.length)].content;
  authorname.innerHTML = request[Math.floor(Math.random() * request.length)].title;  
});

我想出的是:

button.addEventListener("click", function() {
  if (drawnquote.length <= 140){
  quotetext.innerHTML = drawnquote;
  } else {

});

^这就是我的想法结束的地方。有人能指出我正确的方向或给出建议吗?谢谢!

PS:如果可能的话,我试图使用vanilla js。

2 个答案:

答案 0 :(得分:0)

当您发送请求时,响应不会立即显示在下一个语句中:

request.send(); 
request.response // will not necessarily be set

当您send()请求时,它的成功最终会触发'加载'事件。在调用send()之前,需要指定在触发事件被触发时调用的偶数侦听器:

request.addEventListener('load', function onLoad () {
    console.log(this.responseText); 
});

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

上查看更多示例

答案 1 :(得分:0)

这里的核心问题是使用异步代码进行分支,这可能很棘手。我看到你也得到一批引号(在你的例子中为20)。这是一个好主意,但如果您获得的20个引号都超过140个字符怎么办?我们将开始只获取一个,然后我将向您展示如何通过获取多个来提高效率。您还没有正确使用XHTMLHttpRequest ...您正在使用它,就像它同步操作一样,但它没有。您必须添加事件侦听器来处理响应。这是一个正确的实现,以获得单一报价,功能化:

function getQuote(maxLength, cb) {
  const request = new XMLHttpRequest();
  request.addEventListener('load', function() {
    const resp = JSON.parse(this.responseText)
    cb(resp[0].content)
  })
  request.open("GET", "https://quotesondesign.com/wp-json/posts?" 
    + "filter[orderby]=rand&filter[posts_per_page]=1", false);
  request.send(); 
}

作为编辑说明,我可能会用承诺做到这一点,但由于我不确定您是否可以使用承诺,我只是使用回调。

无论长度如何,都会得到单引号。你可以这样使用它:

getQuote(140, function(quote) {
  console.log(quote)
})

现在让我们考虑如果第一个引用太长则获得另一个引用的问题。因为Ajax是异步的,所以你不能只写一个循环。在这种情况下实现这一目标的最简单方法是使函数递归:

function getQuote(maxLength, cb) {
  const request = new XMLHttpRequest();
  request.addEventListener('load', function() {
    // note that we're stripping out HTML -- probably don't want
    // to include that in the length
    const quote = JSON.parse(this.responseText)[0].content
      .replace(/<[^>]+\/>/g, '')
      .trim()
    // if it doesn't match our length requirements,
    // recursively call the function again
    if(quote.length > maxLength) return getQuote(maxLength, cb)
    cb(quote)
  })
  request.open("GET", "https://quotesondesign.com/wp-json/posts?"
    + "filter[orderby]=rand&filter[posts_per_page]=1", false);
  request.send(); 
}

到目前为止一直这么好......问题是,每次运行时,我都会遇到“超出最大调用堆栈大小”的异常。这意味着它循环通过16,000 - 一些引号,并且它们都大于140.所以你所做的可能是一个傻瓜的差事。但是,我们可以通过每个请求获得更多报价来查看320,000个引号:

function getQuote(maxLength, cb) {
  const request = new XMLHttpRequest();
  request.addEventListener('load', function() {
    const quotes = JSON.parse(this.responseText)
    for(let quote of quotes) {
      quote = JSON.parse(this.responseText)[0].content
        .replace(/<[^>]+\/>/g, '')
        .trim()
      // we found a short quote!
      if(quote.length <= maxLength) return cb(quote)
    }
    // we didn't! have to recursively call the function again
    return getQuote(maxLength, cb)
  })
  request.open("GET", "https://quotesondesign.com/wp-json/posts?"
    + "filter[orderby]=rand&filter[posts_per_page]=20", false);
  request.send(); 
}

即使这样,我也超过了最大调用堆栈大小。所以看起来这个特定的数据库没有很多(或任何)小于140个字符的引号......但至少你现在有一个算法模板。