当前位置: 首页 > 知识库问答 >
问题:

html2canvas - js setTimeout 执行时机的先后顺序怎么确定?

南宫龙野
2024-02-06

react 代码中有两个setTimeout,都没有写时间,用来实现等页面渲染完成后再执行,但是通过多次尝试后发现两段逻辑的执行顺序并不绝对,

export default class BarcodeList extends Component {    // 父组件调用,相当于入口函数    showFun=()=>{            this.setState(...)            this.setState(...)            this.setState(...)            setTimeout(()=>{                 //第二部分需要页面渲染完成后执行的逻辑            })    }    inputBarcode=()=>{        setTimeout(()=>{            //第一部分需要页面渲染完成后执行的逻辑        })    }    render() {        this.inputBarcode()            <div>               .....            </div>    }}

我知道写在生命周期钩子中可以确保执行顺序,vue不仅可以写在钩子里,还专门提供了个$nexttack,也可以设置两个很短但不一样长的时间来实现,但我想知道现在的执行顺序为什么不绝对?不是应该是先进先出,谁先脱离线程加入任务流,最后就谁先被加载执行吗?
是因为前面有多个 setState 导致的吗?求指教

共有1个答案

许照
2024-02-06

在JavaScript中,setTimeout函数的执行顺序并不是按照它们被添加到任务队列的顺序来的,而是由浏览器的事件循环(Event Loop)来决定的。

当你调用setTimeout时,JavaScript引擎会将这个函数放入任务队列中,等待当前的事件循环迭代结束之后,再从任务队列中取出任务来执行。这个过程是由浏览器的内部机制来控制的,因此并不能保证setTimeout函数的执行顺序。

在你的例子中,由于setTimeout中的代码块是异步执行的,所以它们不会按照你预期的顺序来执行。即使你先调用this.inputBarcode(),也不一定会在this.showFun()之前执行。这是因为setTimeout中的代码块会在当前的事件循环迭代结束之后,由事件循环来决定它们的执行顺序。

如果你需要确保特定的代码块按照特定的顺序执行,你可以使用回调函数或者Promise来实现。你可以在第一个setTimeout的回调函数中调用第二个setTimeout,这样就可以保证第二个setTimeout中的代码块会在第一个之后执行。

下面是一个使用回调函数的示例:

export default class BarcodeList extends Component {  // 父组件调用,相当于入口函数  showFun = () => {    this.setState(...);    this.setState(...);    this.setState(...);    setTimeout(() => {      // 第二部分需要页面渲染完成后执行的逻辑      this.inputBarcode();    });  }  inputBarcode = () => {    setTimeout(() => {      // 第一部分需要页面渲染完成后执行的逻辑    });  }  render() {    this.showFun();    return (      <div>        ...      </div>    );  }}

在这个示例中,当showFun方法被调用时,它会设置三个状态,然后使用setTimeoutinputBarcode方法放入任务队列中。当inputBarcode方法被调用时,它也会使用setTimeout将一个空的任务放入任务队列中。由于回调函数的使用,可以保证inputBarcode方法会在showFun方法之后执行。

 类似资料:
  • 本文向大家介绍vue.js页面加载执行created,mounted的先后顺序说明,包括了vue.js页面加载执行created,mounted的先后顺序说明的使用技巧和注意事项,需要的朋友参考一下 created页面加载未渲染html之前执行。 mounted渲染html后再执行。 由于created在html模板生产之前所以无法对Dom进行操作而mounted可以。 补充知识:关于Vue子组件

  • 问题内容: 作者:HappyLittleFish 问题答案:

  • 问题内容: 给定以下函数调用: 的执行顺序和未指定,所以可以之前被调用或之前在。 是否指定函数参数表达式的执行顺序或未指定的顺序? 问题答案: 从Java语言规范(关于表达式)中: 15.7.4从左到右评估参数列表 在方法或构造函数调用或类实例创建表达式中,参数表达式可能出现在括号内,以逗号分隔。每个参数表达式似乎都在其右侧任何参数表达式的任何部分之前被完全评估。

  • 问题内容: 我试图理解这段代码,不确定为什么第二遍在第一遍之前执行。如果有人真的可以帮助我,那就太好了! 输出: 问题答案: 您没有任何内容可以显式同步两个goroutine的顺序。如果运行足够的时间,您将看到调用以不同的顺序进行打印。当执行goroutine时,由于它们是并发操作,因此无法保证它们将何时执行和/或完成。您需要使用各种标准库程序包或通道本身来同步并发运行的goroutine的执行。

  • 问题内容: 我试图弄清楚为什么我的一个css类似乎覆盖了另一个(而不是相反) 这里我有两个CSS类 在我看来,我打电话给 字体(重叠元素)显示为10px而不是20px-有人可以解释为什么会这样吗? 问题答案: 有几条规则(按此顺序应用): 内联css(html样式属性)覆盖样式标签和css文件中的css规则 较具体的选择器优先于较不具体的选择器 如果两个规则具有相同的特异性,则稍后出现在代码中的规

  • 问题内容: 我在mysql排序中寻找一些调整,我通常从表中选择记录,然后按Name(varchar)ASC排序记录, 但编号始终是第一位的 这是我的问题的一些示例( 注意。mysql首先用0-9排序记录 ) 我想要的是字母顺序,然后是数字 所需的输出 问题答案: 使用以下子句: