简体   繁体   English

Vuejs 和 Axios 发出多个 get 请求

[英]Vuejs & Axios make multiple get requests

I have a simple Vue script, learning Vue for the first time:我有一个简单的Vue脚本,第一次学习Vue:

 <!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script> </head> <body> <div id="watch-example"> <p> Ask a yes/no question: <input v-model="question" type="text"> <img v-bind:src="image"> </p> <p>{{ answer }}</p> </div> <script> let watchExample = new Vue({ // Root element of app el : '#watch-example', // Properties keep track of data : { question : '', answer : 'I cannot give you an answer until you ask a question!', image : '', }, watch : { question : function(newVal, oldVal) { const vm = this; vm.answer = 'Waitinng for you to stop typing.'; setTimeout(function() { vm.getAnswer(); }, 350); } }, // App methods methods : { getAnswer: function() { const vm = this; if(!vm.question.includes('?')) { vm.answer = 'Questions usually contain a question mark'; vm.image = ''; return; } vm.answer = 'Thinking...'; setTimeout(function() { axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = response.data.answer; vm.image = response.data.image; }); }, 500); } } }); </script> </body> </html>

I noticed that when I type a question, containing a question mark( ? ) too fast, it makes multiple requests, and I get multiple responses.我注意到当我输入一个包含问号( ? )的问题太快时,它会发出多个请求,并且我得到多个响应。 It clears out images upon multiple returned responses and adds new ones.它会根据多个返回的响应清除图像并添加新的响应。 If I type a question slowly, only one response is returned.如果我缓慢地键入一个问题,则只返回一个响应。

console.log(response) shows the multiple responses in the console. console.log(response)显示控制台中的多个响应。

How can I make only one request to get one response to a question no matter the typing speed?无论打字速度如何,我怎样才能只提出一个请求来获得一个问题的回复?

What you need here is debounce from lodash你需要的是从lodash debounce

A good example was given in the Vue documentation Vue 文档中给出了一个很好的例子

Pay attention to this particular code, as an example:注意这个特定的代码,例如:

created: function () {
    // _.debounce is a function provided by lodash to limit how
    // often a particularly expensive operation can be run.
    // In this case, we want to limit how often we access
    // yesno.wtf/api, waiting until the user has completely
    // finished typing before making the ajax request. To learn
    // more about the _.debounce function (and its cousin
    // _.throttle), visit: https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },

Currently your are just delaying your call by wrapping it in a setTimeout.目前,您只是通过将其包装在 setTimeout 中来延迟您的通话。 I think you're trying to accomplish a debounce effect.我认为您正在尝试实现debounce效果。

Lodash has this function but if you don't already use lodash and don't want to include it in your project you could easily write it yourself in a few lines of code. Lodash 有这个功能,但是如果你还没有使用 lodash 并且不想将它包含在你的项目中,你可以很容易地用几行代码自己编写它。

You could just restart the timer on every change (ie, stop the current timer if any, and then start another timer).您可以在每次更改时重新启动计时器(即,如果有的话,停止当前计时器,然后启动另一个计时器)。 Note that setTimeout() returns its associated timer ID, which you could pass to clearTimeout() to stop the timer.请注意, setTimeout()返回其关联的计时器 ID,您可以将其传递给clearTimeout()以停止计时器。 Your code should look similar to this:您的代码应类似于以下内容:

watch: {
    question : function(newVal, oldVal) {
        ...

        clearTimeout(this._timerId);
        this._timerId = setTimeout(function() {
            vm.getAnswer();
        }, 350);
    }
},

 <!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script> </head> <body> <div id="watch-example"> <p> Ask a yes/no question: <input v-model="question" type="text"> <img v-bind:src="image"> </p> <p>{{ answer }}</p> </div> <script> let watchExample = new Vue({ // Root element of app el : '#watch-example', // Properties keep track of data : { question : '', answer : 'I cannot give you an answer until you ask a question!', image : '', }, watch : { question : function(newVal, oldVal) { const vm = this; vm.answer = 'Waitinng for you to stop typing.'; clearTimeout(this._timerId); this._timerId = setTimeout(function() { vm.getAnswer(); }, 350); } }, // App methods methods : { getAnswer: function() { const vm = this; if(!vm.question.includes('?')) { vm.answer = 'Questions usually contain a question mark'; vm.image = ''; return; } vm.answer = 'Thinking...'; setTimeout(function() { axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = response.data.answer; vm.image = response.data.image; }); }, 500); } } }); </script> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM