如何等待请求和用户输入?

How to wait for request and user input?

假设加载组件时我发出异步请求。该组件还有一个提交按钮,用户可以按下该按钮触发依赖于原始请求结果的功能。如何延迟执行触发函数直到异步请求完成?

如果这没有意义,让我举个例子。 MyComponentmounted 上发出异步请求 getRandomColor()MyComponent 的模板有 <button @click="handleClick">handleClick 调用了一些函数 saveColor()。如何确保在我的异步 getRandomColor() 完成之前不调用 saveColor()

我目前正在使用 Vue.js,但我认为这个问题适用于所有 javascript。

您可以通过在按钮元素中添加 :disabled 属性来实现此目的。 :disabled 的值将基于响应。即如果有响应则启用它否则禁用。

工作演示:

const app = Vue.createApp({
  el: '#app',
  data() {
    return {
        buttonText: 'Call Me!',
      apiResponse: [],
      isDisabled: false
    }
  },
  methods: {
    saveColor() {
        console.log('saveColor method call');
    }
  },
  mounted() {
    axios.get("https://jsonplaceholder.typicode.com/users").then(response => {
      this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled.
    }).catch((error) => {
        console.warn('API error');
        });
  }
})
app.mount('#app')
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="app">
  <button v-on:click="saveColor()" :disabled="!apiResponse.length">{{ buttonText }}</button>
</div>

根据 post 的作者添加的评论添加以下代码段。

What if I didn't want to use the disabled button? Is there a way to make the button handler wait for the request to finish before it continues execution?

const app = Vue.createApp({
  el: '#app',
  data() {
    return {
        buttonText: 'Call Me!',
      apiResponse: [],
      isDisabled: false
    }
  },
  methods: {
    saveColor() {
        console.log('saveColor method call');
    }
  },
  mounted() {
    axios.get("https://jsonplaceholder.typicode.com/users").then(response => {
      this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled.
    }).catch((error) => {
        console.warn('API error');
        });
  }
})
app.mount('#app')
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="app">
  <button v-on:click.prevent="apiResponse.length ? saveColor() : {}">{{ buttonText }}</button>
</div>