手表是异步的吗?

WoJ*_*WoJ 5 javascript vue.js

radioStatus在一个Vue实例中观察一个变量:

watch: {
    radioStatus: function(val) {
      if (!this.discovery) {
        $.ajax({ url: '/switch/api/radio/' + (val ? 'on' : 'off') })
      }
    }
Run Code Online (Sandbox Code Playgroud)

它可以在页面重新加载时触发的 AJAX 调用中修改:

$.ajax({
  url: "/api",
  cache: false
})
  .done(function(response) {
    vm.discovery = true;
    vm.radioStatus = response.radio.ison;  // <-- the change I mention below is here
    vm.discovery = false;
  });
Run Code Online (Sandbox Code Playgroud)

我可以假设所有由radioStatus更改触发的方法都将在转到下一行(即vm.discovery = false)之前完成吗?

我担心的是,它vm.discovery是由多个监视变量使用的标志(与 相同radioStatus),并且它会在监视变量的功能完成之前翻转。

Man*_*ani 8

是的,观察者是异步的。参考:https : //vuejs.org/guide/computed.html#Watchers

引自上面的链接:

观察者

虽然计算属性是...当您想要执行异步或昂贵的操作以响应更改的数据时,这是最有用的。

在上述情况下,vm.discovery = false;将在进入watch. 如果您设置vm.discoveryfalse,那么您在内部的 ajax 调用radioStatus将始终被执行。

为避免这种情况,您可以尝试vm.$nextTick()以下操作:

$.ajax({url: "/api", cache: false})
    .done(function(response) {
        vm.discovery = true;
        vm.radioStatus = response.radio.ison;
        vm.$nextTick( () => {
            console.log("Setting vm.discovery to false");
            vm.discovery = false;
        });
    });
Run Code Online (Sandbox Code Playgroud)

这又是一件棘手的事情——因为你的radioStatus()回调 inwatch也将发生在nextTickonly 中。但是假设 watch 是由前一行本身 ( vm.radioStatus = ...)触发的,从技术上讲,它应该先进入队列,因此更早完成。您将不得不通过一系列console.log声明进行确认。