watch监听两个数据 第一个是promise函数第二个是宏任务 为什么promise函数没有执行完毕就去执行了宏任务?

@Watch('videoId')
watchLaserMethane(id) {
    let p: any = this.getLaserMethaneLineList(id)
    console.log("333333333333333")
    p.then((data)=>{
        console.log("1111111111111111111111")
        this.lineData = data
        if (this.lineData.length) {
            this.pointData = this.lineData[0].points
        } else {
            this.pointData = []
        }
    })
}
getLaserMethaneLineList(videoId) {
  let params = {
      videoId: videoId
  }
   return new Promise((resolve, reject) => {
       getLaserMethaneLineList(params).then( (res) => {
          let { code, data } = res.data
          if (code === 200) {
              resolve(data)
          } else {
              reject()
          }
      })
  })
}

@Watch('patrolSettingShow')
watchPatrolSettingShow(newVal) { 
    if (newVal) {
        setTimeout(()=>{
            console.log("2222222222222222222222222222")
            if (this.lineData.length) {
                this.$nextTick(()=>{
                    this.$refs.lineTable.setCurrentRow(this.lineData[0])
                })
            }
        })
    }
}

监听了两个数据,vidoeId先传过来,patrolSettingShow后传过来
理想的执行是watchLaserMethane()先执行,然后再去执行watchPatrolSettingShow()中的宏任务,
打印顺序是
3333333333333333333
1111111111111111111
2222222222222222222
但是在实际执行过程中,执行顺序如下:
3333333333333333333
2222222222222222222
1111111111111111111

请问为什么会出现这种setTimeout先于.then执行,跟watch执行顺序有关,还是函数同步异步有关。
如果想要变成watchLaserMethane()全部执行完毕再去执行watchPatrolSettingShow(),上述代码需要怎么改进。

阅读 1.9k
2 个回答

改成同步的就行 async await

@Watch('videoId')
async watchLaserMethane(id) {
    let data: any = await this.getLaserMethaneLineList(id)
    console.log("333333333333333")
  console.log("1111111111111111111111")
        this.lineData = data
        if (this.lineData.length) {
            this.pointData = this.lineData[0].points
        } else {
            this.pointData = []
        }
}
getLaserMethaneLineList(videoId) {
  let params = {
      videoId: videoId
  }
   return new Promise((resolve, reject) => {
       getLaserMethaneLineList(params).then( (res) => {
          let { code, data } = res.data
          if (code === 200) {
              resolve(data)
          } else {
              reject()
          }
      })
  })
}

@Watch('patrolSettingShow')
watchPatrolSettingShow(newVal) { 
    if (newVal) {
        setTimeout(()=>{
            console.log("2222222222222222222222222222")
            if (this.lineData.length) {
                this.$nextTick(()=>{
                    this.$refs.lineTable.setCurrentRow(this.lineData[0])
                })
            }
        })
    }
}

因为你的 getLaserMethaneLineList方法是一个网络请求,可能一直在请求网络,要等一会儿才能 resolve,要等它 resolve 之后 watchLaserMethane 里面的 .then 里面的代码才会放到任务队列。而你的 setTimeout 是没有延时的,所以里面的代码在执行到的时候立刻放到了任务队列。所以 setTimeout 在这里优于 .then 执行

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题