VueJS Vuex - 解决状态变化的承诺?

Posted

技术标签:

【中文标题】VueJS Vuex - 解决状态变化的承诺?【英文标题】:VueJS Vuex - Promise that resolves on state change? 【发布时间】:2019-03-11 19:26:58 【问题描述】:

是否可以创建一个 Promise,一旦全局 vuex 存储中的变量发生更改,它就会解析?

我有一个变量在状态存储中初始化为null,并将通过异步调用填充。 应用程序的不同部分取决于该变量是 truefalse 并且应该在它仍然是 null 时等待。

有没有办法干净地等待这个变量的变化?

【问题讨论】:

谁进行异步调用?你不能立即用承诺填充变量吗? 你的意思是把promise本身放在全局存储中?我还没有尝试过,但即使它可以工作,我也觉得不太对劲......全局状态不应该处于定义状态吗?我更愿意在 while(state.foo == undefined) wait(100); resolve(state.foo) 之外创建一个承诺,但我不知道这是否可行以及如何实现...... 【参考方案1】:

您可以在表达式或函数上vm.$watch,然后wrap that with a promise。

function watch(vm, fn) 
  return new Promise(resolve => 
    const watcher = vm.$watch(fn, (newVal) => 
      resolve(newVal);
      watcher(); // cleanup;
    );
  );

这会让你做类似的事情:

let change = await watch(vm, () => state.foo); // will resolve when state.foo changes

async function 中。

请注意,一般来说这不是一个很好的模式,在大多数情况下,为此使用computed property(而不是承诺)更可取且更简单。

【讨论】:

我最终只是按照答案中的描述进行了轮询:***.com/questions/30505960/… 但是您的解决方案看起来确实很有趣,下次我会记住这一点! @TommyF 请小心为多个值执行此操作,因为它绕过了 Vue 自己的响应系统,该系统是为侦听更改而构建的。 我明白了,我只是在实际的 vue 组件之外使用它。但是感谢您的警告。 明确地说,我承认在某些情况下使用轮询可能更合适且更容易。例如,因为即使你重构了 vue,它也会继续工作。【参考方案2】:

与本杰明的回答类似,而不是您所要求的,只是另一种选择。你可以subscribe 而不是观察状态变化,当特定类型的突变发生并将其包装到 Promise 中。

new Promise(resolve => 
      let unsubscribeFn = this.$store.subscribe(mutation => 
        if (mutation.type === "MY_MUTATION") 
          unsubscribeFn();
          resolve();
        
      );
    );

【讨论】:

以上是关于VueJS Vuex - 解决状态变化的承诺?的主要内容,如果未能解决你的问题,请参考以下文章

从承诺解决方案调用时,Vuex 商店未更新

从 vuex 操作返回 axios 承诺

Youtube API未捕获(在承诺中)错误:请求失败,状态码为403

Vuex Action - 返回 Axios Promise

Vue.js:vuex 操作中未捕获的承诺

从 vuex 存储操作中的承诺返回错误