[英]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.