文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue踩不完的异步之坑及解决

2024-04-02 19:55

关注

Js 的异步确实完美地解决了单线程的问题,但是同时也会带来许多问题。而且随着用的框架越来越多,越来越复杂,定位问题的难度也随之上升。

不知为什么,总觉得Vue 的断点调试相比于不使用框架的情况下更难用,这可能也是花了一个小时才找到问题产生的根源的原因。废话少说,以下便是问题产生的全过程以及查找问题的流程与逻辑梳理。

1. 任务需求分析

1.1 两个页面,两个组件

任务需求涉及到两个页面和两个组件之间的恩怨纠纷,它们的关系如下:

1.2 需求描述

2. 功能是如何实现的?

2.1 以前端思维消化需求

2.2 代码实现 (简化版)

<userTable
  :tableType="1"
  :userList="userList"></userTable>
<modalUserList
  @closeModal="CloseModal"
  :id="chosenGroupId"
  :show="showUserList"></modalUserList>
<userTable
  :tableType="2"
  :userList="userList"></userTable>
ShowGroupUserList (index, row) {
  this.showUserList = true
  // 通知孙子获取用户列表
  this.SetAuthGetUserListTrue() // 通知孙子组件发送ajax 请求获取数据
  this.SetAuthGroupId(row.id)   // 设置authGroupId
}
mounted () {
  this.GetUserList()
  // 权限管理点击按钮时才获取用户列表
  // 是通过点击权限管理的组成员按钮进入的
  if (this.authGetUserList) {
    this.GetUserListByGroupId(this.authGroupId)
    // 重新将刷新设为false
    this.SetAuthGetUserListFalse()
  }
}
watch: {
  authGetUserList: function (newV, oldV) {
    // 检查是否需要根据选择的权限组获取用户列表
    if (newV) {
      console.log(this.tableType)
      if (this.tableType == 1) {
        this.GetUserList()
      } else {
        this.GetUserListByGroupId(this.authGroupId)
      }
      // 重新将刷新设为false
      this.SetAuthGetUserListFalse()
    }
  }
}

2.3 代码翻译 

虽然贴了这么多代码,但是比较碎片化,一时半会可能不太好理清楚其中的逻辑所以这里再稍加解释,以上代码翻译成中文后大意如下:

3. 遇到了什么问题?

4. 问题是如何解决的?

4.1 问题分析

分析一下问题的表现形式,针对问题的产生大概有以下两种猜测:

4.2 开始解决

查了一下代码发现tableType 传值并没有出现错误,第一条猜测不成立,那么大概率就是由于数据的异步获取导致的问题了。(虽然想不明白为什么获取到数据后没有触发页面重绘)

可能解决异步问题的一个猜想:等到数据加载完成了再显示弹框,而不是用户点击按钮的瞬间就显示(代价是爷孙组件通信),于是尝试在孙子组件加载数据完成时才通知爷爷组件显示弹框(父亲组件)。尝试失败,因为如果不先显示弹框,孙子组件就没有挂载,那就不能跟爷爷组件进行通信。

下一步,先显示父亲组件,等孙子组件获取数据成功后再显示孙子组件。设想功能成功实现,但是依然没有解决权限管理页面会显示所有用户列表的bug!

4.3 断点调试显神威

这个时候才想起来还是可以用断点调试的(使用Vue 以来基本都是用vue-dev-tools 进行调试了,刚好今天vue-dev-tools 又崩了...)。打断点一步一步走,发现在权限管理点击了组成员按钮的时候依然会在最后调用GetUserList 方法而不是GetUserListByGroupId 方法。为啥嘞?

回去看代码,2.2 中最后两段代码,mouted 中的写法,原来真的是有!问题!的!mounted 中的写法看起来是限先执行GetUserList,然后根据情况执行GetUserListByGroupId。可是由于异步的问题GetUserListByGroupId 方法获得返回值的时间不一定在GetUserList 之后,这就导致了bug 的不稳定性,有时正常,有时出问题了!

修改后的mounted 代码如下:

mounted () {
  // 权限管理根据权限组id 获取用户列表
  if (this.authGetUserList) {
    this.GetUserListByGroupId(this.authGroupId)
    // 重新将刷新设为false
    this.SetAuthGetUserListFalse()
  } else {
    // 用户管理直接获取所有用户列表
    this.GetUserList()
  }
}

呵呵哒,异步的坑踩了一个又一个!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯