当数据已经到达第一个响应时,删除发送 Xmlhttprequest 的开销

Removing the Overhead of sending Xmlhttprequest when the the data already arrived in the first response

我正在构建一个随机报价生成器,为此我正在使用 Xmlhttprequest 从 API 获取报价。 当有人点击生成报价按钮时,一个 http get 请求被发送到 Api 并且每次点击都会显示随机报价。一切对我来说都很好,但唯一的问题是每次点击我都会发送一个新的 http 请求,我想发送一次请求然后继续显示响应数据。我在这里尝试使用 abort() 方法,但我仍然面临一些问题。 有人可以指导我如何实现吗?

MY html files looks something like this
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="assets/styles/app.css"> 
    <script src="assets/scripts/xmlhttprequest.js" defer></script>
    <!-- <script src="assets/scripts/app.js"></script> -->

</head>
<body>
    <div id="main">
        <h2 id="heading">Random Quotes Generator</h2>
        <div id="quotes">
            <button class="btn btn-primary btn-lg">Generate Quotes</button>
            </div>
            <div>
               <article></article>
               <p id="authorName"></p>
    </div>
    
        
        
    </div>
</body>
</html>


CSS code

body{

    background-color:darkcyan;
}

#heading{

    font-style: oblique;
    display: flex;
    justify-content: center;
    margin-left: 60px;
   margin-top: 30px;
    
}
#quotes{

    margin-left: 45%;
    margin-top: 50px;
    
    
}
.inner{
    background-color:lightblue;
    border: 0px solid green;
    border-style:groove;
    padding:90px; /*--100*/
    margin-left: 30%;
    margin-top: 50px;
    margin-bottom:20px;
    width:40%;
    font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    font-weight:600;
    font-size: 20px;
    color:saddlebrown;
}

#authorName{
    text-align:right;
    color: lightseagreen;
}


Javascript code -
const button=document.querySelector('button')
const innerQuotesDiv=document.querySelectorAll('div')[2]
const article=innerQuotesDiv.firstElementChild
const authorName=article.nextElementSibling
    
function generateRandomIndex(length){

    console.log(length)
    return (Math.floor(Math.random()*length))
  }

  function getQuotes(){
    
   // console.log(noOfTimesBtnClicked)
    let xhr=new XMLHttpRequest()
    xhr.open('GET','https://type.fit/api/quotes')
    xhr.onload=function(){

      let quotes=JSON.parse(xhr.response)
        console.log(quotes)
        let index=generateRandomIndex(quotes.length)
        innerQuotesDiv.classList.add('inner')
        article.textContent=quotes[index].text 
        if(!quotes[index].author)
       {
           authorName.textContent='Anonymous'  
       }
       else{
        authorName.textContent=quotes[index].author  
       }
    }
    
    xhr.onerror=function(){

      console.log(xhr.response)
      console.log(xhr.status)
      alert('something went wrong')
  }
  xhr.send() 
  
  }

  function abortGetRequest(xhr){
    
    xhr.abort()
  }



  button.addEventListener('click',()=>{

    //console.log('clicked')
    


    getQuotes()

    

})


JS code in which i have tried to use abort() --


const button=document.querySelector('button')
const innerQuotesDiv=document.querySelectorAll('div')[2]
const article=innerQuotesDiv.firstElementChild
const authorName=article.nextElementSibling


function generateRandomIndex(length){

    console.log(length)
    return (Math.floor(Math.random()*length))
  }

  function getQuotes(){
    
   // console.log(noOfTimesBtnClicked)
    let xhr=new XMLHttpRequest()
    xhr.open('GET','https://type.fit/api/quotes')
    xhr.onload=function(){

      let quotes=JSON.parse(xhr.response)
        console.log(quotes)
        let index=generateRandomIndex(quotes.length)
        innerQuotesDiv.classList.add('inner')
        article.textContent=quotes[index].text 
        if(!quotes[index].author)
       {
           authorName.textContent='Anonymous'  
       }
       else{
        authorName.textContent=quotes[index].author  
       }
    }
    
    xhr.onerror=function(){

      console.log(xhr.response)
      console.log(xhr.status)
      alert('something went wrong')
  }
  xhr.send() 
  abortGetRequest(xhr)

  }

  function abortGetRequest(xhr){
    
    xhr.abort()
  }

function displayQuotes(quotes){

  let index=generateRandomIndex(quotes.length)
  innerQuotesDiv.classList.add('inner')
  article.textContent=quotes[index].text 
  if(!quotes[index].author)
 {
     authorName.textContent='Anonymous'  
 }
 else{
  authorName.textContent=quotes[index].author  
 }

}

  button.addEventListener('click',()=>{

    //console.log('clicked')
    


    getQuotes()

   
    

})

使用 fetch API - 我在引号中得到未定义我认为这是因为引号在 onload 函数之前执行。我如何才能做到同步或有任何其他方式我可以使用来自分配给 quote 变量的承诺的数据。

const button=document.querySelector('button')
const innerQuotesDiv=document.querySelectorAll('div')[2]
const article=innerQuotesDiv.firstElementChild
const authorName=article.nextElementSibling
let quotes;
// console.log(button)
// console.dir(innerQuotesDiv)
 //console.log(article)
 //console.log(authorName)

 quotes=window.addEventListener('load',fetchApi)
function generateRandomIndex(length){

  console.log(length)
  return (Math.floor(Math.random()*length))
}

function fetchApi(){

   let d=fetch('https://type.fit/api/quotes')
    .then(response=>{
        return response.json()
    })
    .then(data=>{
        console.log(data)
        return data
    })
    console.log(d)
    return d
}




function changeQuotes(){
     
    console.log(quotes)
    let index=generateRandomIndex(quotes.length)
    innerQuotesDiv.classList.add('inner')
    article.textContent=quotes[index].text 
    if(!quotes[index].author)
   {
       authorName.textContent='Anonymous'  
   }
   else{
    authorName.textContent=quotes[index].author  
   }

}
  button.addEventListener('click',()=>{
      
         changeQuotes()
  })

我没有测试这个,但是...

window.addEventListener('DOMContentLoaded', ()=>{
    const innerQuotesDiv=document.querySelectorAll('div')[2]
    const article=innerQuotesDiv.firstElementChild
    const authorName=article.nextElementSibling

    function changeQuotes(quotes) {
        console.log(quotes)
        let index = generateRandomIndex(quotes.length)
        innerQuotesDiv.classList.add('inner')
        article.textContent = quotes[index].text
        if (!quotes[index].author) {
            authorName.textContent = 'Anonymous'
        } else {
            authorName.textContent = quotes[index].author
        }
    }

    const request= fetchData('https://type.fit/api/quotes');

    document.querySelector('button').addEventListener('click',()=>{
           request.then(changeQuotes);
    })
})

function generateRandomIndex(length){
    console.log(length)
    return (Math.floor(Math.random()*length))
}

function fetchData(url) {
    return fetch(url)
        .then(response => {
            return response.json()
        })
        .then(data => {
            console.log(data)
            return data
        })
}