关于javascript:一个由父子组件传值和nextTick引发的关于宏任务和微任务的思考

这所有要从最近接手了一段祖传的代码开始说起。。。

起因和解决形式

作为一名前端老司机(自封),也不晓得是不是招我进来的老哥看上了我的我的项目经验还是老板的无心为之(年底都是老我的项目优化),总而言之我接手了一段老的n手(n>3)代码,尽管提交工夫是一年前,然而这ES5语法好像是15-17年的产物,让我回想到我刚工作的时候接触的网页,有种亲切的感觉(不是)。

在一顿梳理之后,我把问题的指标锁定在了一对父子组件上,子组件内有两个函数:

  1. 依据watch监听的函数,在父组件上用data管制组件展现的同时,咱们要在这里做一个localStorage.setItem和赋值子组件data的操作,在每次关上时传入以后定位城市。
  1. 一个须要localStorage.getItem获取数据而后做申请与后端交互的函数,原有逻辑会在父组件上通过ref去调用,为了逻辑拆散和防止反复调用,不把(2)退出到(1)的逻辑里

如果是react的setState,我会抉择把(2)函数传入setState的回调,然而这可是vue2啊。在他们两个同时调用的场景下,因为通过了watch的拦挡,(2)必定会先于(1)触发。于是,咱们就在(2)调用localStorage.getItem和赋值子组件data的时候在Storage外层包裹上$nextTick,localStorage.getItem就能正确拿到数据了,完满~

父组件调用:

this.isshowseach = true;
this.$refs.seachadrFuc.mapData(localStorage.getItem("currentCity"));

子组件watch和methods:

  watch: {
    showOnoff: {
      handler(val) {
        console.log("showOnoff触发");
          // 默认把以后定位的城市填入
           this.selectCity = this.city;
             localStorage.setItem("selectCity", this.selectCity);
        }
      },
    },
  },
  methods: {
    mapData(val) {
      console.log("mapData触发");
        this.$nextTick(() => {
          this.getupList();
        });
    },

    getupList() {
     console.log(this.selectCity) //    胜利赋值为this.city
    }

}

剖析:

watch这里应用的Object.observe(proxy同理)监听,属于微工作,所以会比同步工作window.localStorage.getItem后执行。
$nextTick的原理是Promise.then、MutationObserver和 setImmediate又或者是setTimeout(fn,0),都属于宏工作,因而window.localStorage.getItem和赋值子组件data包裹上宏工作$nextTick后,又会比watch后执行。

谢谢观看!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理