<p>你好,我有一个问题:在main.js中,我有一个全局函数<code>getSites</code>,用于从API检索站点列表。</p><p>
这个函数使用async/await工作,并异步返回站点数据。</p><p>
我还有一个全局变量叫做<code>lockSitesLoading</code>,当我开始从API获取数据时,我将其设置为true,我需要这个变量来防止客户端向服务器发出新请求。</p><p>
在第一个函数<code>getSites</code>中,我需要检查这个变量<code>lockSitesLoading</code>,如果它为true,就开始监视它直到它变为false。在这一点上,我想递归调用<code>getSites</code>。</p><p>
问题现在开始了,因为当我开始监视变量时,这个函数并不等待变量变为false,而是返回<code>undefined</code>。</p><p>
这里是我的代码:</p>
<p>组件.vue:</p>
<pre class="brush:php;toolbar:false;">async mounted() {
let vm = this;
const sites = await vm.getSites();
vm.sites = sites.data
},</pre>
<p>main.js:</p>
<pre class="brush:php;toolbar:false;">async getSites() {
let vm = this;
if (vm.$store.state.lockSitesLoading) {
vm.$watch('$store.state.lockSitesLoading', () => vm.getSites());
} else {
return vm._getSitesOnline();
//这是实际从服务器获取数据的函数
}</pre>
<p>我尝试以这种方式解决,但不起作用。有什么想法吗?</p>
不清楚你是否设置了
lockSitesLoading = true,也不清楚你在哪里设置了。这是一个可工作的示例。
Vue.use(Vuex) const store = new Vuex.Store({ state: { sites: [], lockSitesLoading: false }, actions: { async loadSites(context) { context.state.lockSitesLoading = true; const sites = await context.dispatch('getSites'); context.state.sites = sites.data; context.state.lockSitesLoading = false; }, async getSites(context) { return new Promise(function(resolve, reject){ setTimeout(function(){ resolve({ data: ['site1', 'site2', 'site3']}) },1000) }) } } }) new Vue( { el:'#app', store: store, async mounted() { await this.$store.dispatch('loadSites') }, computed: { sites() { return this.$store.state.sites }, lockSitesLoading() { return this.$store.state.lockSitesLoading } }, watch: { lockSitesLoading(newVal, oldVal) { console.log(`lockSitesLoading: ${oldVal} -> ${newVal}`) } } } )#app { line-height: 1.75; } [v-cloak] { display: none; }<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script> <script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script> <div id="app" v-cloak> sites: {{sites}}<br/> lockSitesLoading: {{lockSitesLoading}} </div>基本上需要一个等待的承诺:
let unwatch; await new Promise(resolve => { unwatch = vm.$watch('$store.state.lockSitesLoading', loading => { if (!loading) { resolve(); } }, { immediate: true }); }); unwatch(); await vm._getSitesOnline();请注意,如果
lockSitesLoading由于某种原因阻止执行,这将导致内存泄漏。使用组合API和VueUse组合式可能有更简洁的方法来实现这一点。