首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么这个promise中的setState更新时间比异步函数中的相同代码要长?

在React中,setState是一个异步操作,它会将更新放入队列中,然后在合适的时机批量执行更新。而异步函数中的代码会立即执行,不会等待setState更新完成。

这种设计是为了提高性能和优化渲染过程。当多次调用setState时,React会将这些更新合并为一个更新,然后进行一次性的渲染,避免了频繁的重复渲染。这样可以减少渲染次数,提高性能。

当我们在异步函数中调用setState时,由于异步函数会立即执行,而setState是异步的,所以在异步函数中的代码执行完毕后,setState的更新可能还没有执行。因此,如果在异步函数中立即访问setState更新后的状态,可能会得到旧的状态值。

为了解决这个问题,React提供了一个回调函数作为setState的第二个参数,可以在更新完成后执行。我们可以在回调函数中访问到最新的状态值。

总结起来,promise中的setState更新时间比异步函数中的相同代码要长,是因为setState是一个异步操作,它会将更新放入队列中,等待合适的时机批量执行,而异步函数中的代码会立即执行,不会等待setState更新完成。为了获取最新的状态值,可以使用setState的回调函数。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

React 中的useState 和 setState 的执行机制

setState和 useState 只在「合成事件」如onClick等和「钩子函数」包括componentDidMount、useEffect等中是“异步”的,在原生事件和 setTimeout、Promise.resolve...这里的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是「合成事件」和「钩子函数」的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”。...「批量更新优化」也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout、Promise.resolve().then 中不会批量更新,在“异步”中如果对同一个值进行多次修改,批量更新策略会对其进行覆盖...在 function component 里面每次更新都是重新执行当前函数,也就是说 setTimeout 里面读取到的 count 是通过闭包获取的,而这个 count 实际上只是初始值,并不是上次执行完成后的最新值...就像下面这样: const [state, setState] = useState({ count: 0 }) 答案是不行,因为即使 state 是个对象,但每次更新的时候,要传一个新的引用进去,这样的引用依然是没有意义

3.2K20

精读《Javascript 事件循环与异步》

with async/await 1 引言 我为什么要选这篇文章呢?...了解 JS Event Loop 的原理,对 setTimeout Promise 这种基础概念不再浮在表层,可以写出更可靠的代码,如果你是前端新人,不要总是因为这个问题挂在一面 :p。...任何同步的代码都只存在于 Call Stack 中,遵循先进后出,后进先出的规则,也就是只有异步的代码(不一定是回调)才会进入 Event Loop 中,哪些是异步代码呢?...而是进入 Event Loop 队列,此时 JS 主线程执行完毕后,且异步时机到了,就会将异步回调中的代码推入 Call Stack 执行。...异步队列是周而复始循环执行的,可以看作是二维数组:横排是一个队列中的每一个函数,纵排是每一个队列。

41540
  • 深入理解React

    setState导致多次渲染带来不必要的性能开销,会将待更新的state放到队列中,等到合适的时机(生命周期钩子和事件)后进行batchUpdate,所以在setState后无法立即拿到更新后的state...因此很多人说setState是异步的,setState表现确实是异步,但是里面没有用异步代码实现。update不是等主线程代码执行结束后才执行的,而是需要手动触发。...如果是给setState传入一个函数,这个函数是执行前一个setState后才被调用的,所以函数返回的参数可以拿到更新后的state。...但是如果将setState在异步方法中(setTimeout、Promise等等)调用,由于这些方法是异步的,会导致生命周期钩子或者事件方法先执行,执行完这些后会将更新队列的pending状态置为false...,这个时候在执行setState后会导致组件立即更新。

    62820

    使用React和Node.js制作音乐类App的一次总结

    JSX语法,比较基本的JSX语法一定是要非常熟练的 ES5/6 TypeScript,为什么需要TS的知识? 为了看懂源码,更好调试代码。...setState的异步同步问题,其实就是上面的事件机制,这个问题遇到的还是非常多的,如果搞不懂,那么调试起来非常困难 React中追求组件化,个人喜欢组件化到极致,这样方便调试,在使用TS和React...在http通信时,如果要将返回的数据setState,那么请注意setState的同异步场景,准确把控渲染和设置状态时间差逻辑,特别是多个请求,可以使用`promise.all 或者在setState的回调函数中发送请求...比如下面这段代码,需要发送10个请求并且将返回的数据整合,再把数组中的10个promise对象的值取出,设置成状态重新渲染。...}) }, 1000); } `如果此时不加定时器,那么会先执行setState的代码,再去执行promise.then里面的逻辑,

    2.1K10

    前端一面高频react面试题(持续更新中)

    通过在 shouldComponentUpdate方法中返回 false, React将让当前组件及其所有子组件保持与当前组件状态相同。传入 setstate函数的第二个参数的作用是什么?...,有时表现出异步setState 只有在 React 自身的合成事件和钩子函数中是异步的,在原生事件和 setTimeout 中都是同步的setState 的异步并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的...,只是合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的异步。...当然可以通过 setState 的第二个参数中的 callback 拿到更新后的结果setState 的批量更新优化也是建立在异步(合成事件、钩子函数)之上的,在原生事件和 setTimeout 中不会批量更新...,在异步中如果对同一个值进行多次 setState,setState 的批量更新策略会对其进行覆盖,去最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新合成事件中是异步钩子函数中的是异步原生事件中是同步

    1.8K20

    前端面试中小型公司都考些什么

    React 中对 JSX 代码的转换依赖的是 React.createElement 这个函数。...变量提升当执行 JS 代码时,会生成执行环境,只要代码不是写在函数中的,就是在全局执行环境中,函数中的代码会产生函数执行环境,只此两种执行环境。...,我们可以直接提前使用在提升的过程中,相同的函数会覆盖上一个函数,并且函数优先于变量提升b() // call b secondfunction b() { console.log('call b...isBatchingUpdates为 true,则把当前组件(即调用了 setState 的组件)放入dirtyComponents 数组中;否则 batchUpdate 所有队列中的更新1.2 为什么直接修改...⼏乎是同步的写法,⾮常优雅错误处理友好,async/await可以⽤成熟的try/catch,Promise的错误捕获⾮常冗余调试友好,Promise的调试很差,由于没有代码块,你不能在⼀个返回表达式的箭头函数中设置断点

    79960

    前端开发面试如何答题才能让面试官满意

    图片setState 只有在 React 自身的合成事件和钩子函数中是异步的,在原生事件和 setTimeout 中都是同步的setState 的异步并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的...当然可以通过 setState 的第二个参数中的 callback 拿到更新后的结果setState 的批量更新优化也是建立在异步(合成事件、钩子函数)之上的,在原生事件和 setTimeout 中不会批量更新...,在异步中如果对同一个值进行多次 setState,setState 的批量更新策略会对其进行覆盖,去最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新合成事件中是异步钩子函数中的是异步原生事件中是同步...为什么会这样呢?当调用 setState 函数时,就会把当前的操作放入队列中。React 根据队列内容,合并 state 数据,完成后再逐一执行回调,根据结果更新虚拟 DOM,触发渲染。...但是容易出现卡顿、抖动的现象;原因是:settimeout任务被放入异步队列,只有当主线程任务执行完后才会执行队列中的任务,因此实际执行时间总是比设定时间要晚;settimeout的固定时间间隔不一定与屏幕刷新间隔时间相同

    1.3K20

    React Native面试知识点

    8.加载bundle的机制 要实现RN的脚本热更新,我们要搞明白RN是如何去加载脚本的。...rn源代码、第三方库、业务逻辑的代码)都在这一个文件里,启动App时会第一时间加载bundle文件,所以脚本热更新要做的事情就是替换掉这个bundle文件。...在 app 中启动页(或 splash 页)编写请求更新的代码(请求包含了本地版本,hashCode、appToken 等信息),微软服务端对比本地 js bundle 版本和微软服务器的版本,如果本地版本低...11.Redux中同步 action 与异步 action 最大的区别是什么 同步只返回一个普通 action 对象。而异步操作中途会返回一个 promise 函数。...当然在 promise 函数处理完毕后也会返回一个普通 action 对象。

    2.9K11

    深入挖掘React中的state

    需要注意的是这里的"异步更新",所谓的异步和Promise以及setTimeout这些微/宏任务是无关的。这点我们在后续会讲到,这也是Vue中异步更新策略不同之处。..."同步更新" 当然上边我们讲到了setState是异步更新,但是我们想要setState实现同步更新,这个时候应该怎么办呢?...setState执行机制 对于setState的更新机制,究竟是同步还是异步。也就是所谓是否是批量更新,可以把握这个原则: 凡是React可以管控的地方,他就是异步批量更新。...比如事件函数,生命周期函数中,组件内部同步代码。 凡是React不能管控的地方,就是同步批量更新。...(这点和Vue大相庭径,vue中是通过nextTick - promise - settimeout)。 react中的异步其实是内部通过一个变量来控制是否是同步或者异步,从而进行批量/单个更新。

    42920

    美团前端经典react面试题整理_2023-02-28

    要提高 React应用的效率,需要按照这两点假设来开发。 传入 setState 函数的第二个参数的作用是什么?...这种机制可以让我们改变数据流,实现如异步action ,action 过滤,日志输出,异常报告等功能 redux-logger:提供日志输出 redux-thunk:处理异步操作 redux-promise...:处理异步操作,actionCreator的返回值是promise 组件更新有几种方法 this.setState() 修改状态的时候 会更新组件 this.forceUpdate() 强制更新 组件件...hooks 为什么不能放在条件判断里 以 setState 为例,在 react 内部,每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中 图片 update...props 的行为只有在构造函数中是不同的,在构造函数之外也是一样的。 这段代码有什么问题?

    1.5K20

    一天梳理完React所有面试考察知识点

    性能优化性能优化,永远是面试的重点,性能优化对于 React 更加重要在页面中使用了setTimout()、addEventListener()等,要及时在componentWillUnmount()中销毁使用异步组件使用...有一个有意思的问题,解释为什么 React setState() 要用不可变值// 父组件中changeList () { this.state.list.push({id: 2}) this.setState...()为异步更新数据const count = this.state.count + 1this.setState({ count: count}, () => { // 这个函数没有默认参数...// 打印更新前的值setState()同步更新数据,在setTimeout()中setState()是同步的setTimeout(() => { const count = this.state.count...是SyntheticEvent合成事件对象与 Vue 事件不同,和 DOM 事件也不同图片为什么要合成事件机制更好的兼容性和跨平台,摆脱传统DOM事件挂载到document,减少内存消耗,避免频繁解绑方便事件的统一管理

    2.8K30

    一天梳理完React面试考察知识点

    性能优化性能优化,永远是面试的重点,性能优化对于 React 更加重要在页面中使用了setTimout()、addEventListener()等,要及时在componentWillUnmount()中销毁使用异步组件使用...有一个有意思的问题,解释为什么 React setState() 要用不可变值// 父组件中changeList () { this.state.list.push({id: 2}) this.setState...()为异步更新数据const count = this.state.count + 1this.setState({ count: count}, () => { // 这个函数没有默认参数...// 打印更新前的值setState()同步更新数据,在setTimeout()中setState()是同步的setTimeout(() => { const count = this.state.count...是SyntheticEvent合成事件对象与 Vue 事件不同,和 DOM 事件也不同图片为什么要合成事件机制更好的兼容性和跨平台,摆脱传统DOM事件挂载到document,减少内存消耗,避免频繁解绑方便事件的统一管理

    3.2K40

    前端面试之React

    难以理解的 class,理解 JavaScript 中 this 的工作方式。 区别: 函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。...子传父是先在父组件上绑定属性设置为一个函数,当子组件需要给父组件传值的时候,则通过props调用该函数将参数传入到该函数当中,此时就可以在父组件中的函数中接收到该参数了,这个参数则为子组件传过来的值 /...使用context,context相当于一个大容器,我们可以把要通信的内容放在这个容器中,这样不管嵌套多深,都可以随意取用,对于跨越多层的全局数据可以使用context实现。...如和使用异步组件 加载大组件的时候 路由异步加载的时候 react 中要配合 Suspense 使用 // 异步懒加载 const Box = lazy(()=>import('....为什么要 throw 它?这就要涉及到 Suspense 的工作原理,我们接着往下分析。

    2.6K20

    前端react面试题总结

    为什么调用 setState 而不是直接改变 state?解答如果您尝试直接改变组件的状态,React 将无法得知它需要重新渲染组件。通过使用setState()方法,React 可以更新组件的UI。...如果需要基于另一个状态(或属性)更新组件的状态,请向setState()传递一个函数,该函数将 state 和 props 作为其两个参数:this.setState((state, props) =>...: 处理异步操作;actionCreator 的返回值是 promise类组件和函数组件之间的区别是啥?...函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。...除以上四个常用生命周期外,还有一个错误处理的阶段:Error Handling:在这个阶段,不论在渲染的过程中,还是在生命周期方法中或是在任何子组件的构造函数中发生错误,该组件都会被调用。

    2.5K30

    react中的内循环与批处理

    先有问题再有答案 要如何理解react内部的事件循环? UI,状态,副作用的依赖关系是如何描述的? 如何理解react中的批处理 react内部多次调用setState和异步多次调用有什么区别?...视图更新 当状态更新发生时,React 会重新计算组件的渲染输出。这个过程涉及到调用组件的渲染函数或组件树的部分,以生成新的虚拟 DOM。...以下是一些批处理可能“失效”或不被应用的情况: 异步操作:只有同步代码中的状态更新会自动被批处理。...在异步操作中(如 setTimeout、Promise、异步事件处理等)触发的状态更新不会被自动批处理,每个状态更新都可能引起一次单独的重新渲染。...setState1(1); setState3(3); setState4(4); 因为当前处于异步函数中 所以这三次state更新会被分到三次不同的队列中 触发三次组件渲染。

    9910

    React高级特性解析

    当父组件渲染到子组件的时候发现异步请求 直接抛出错误 捕获的结果是个promise ComponentDidCatch捕获到这个promise的异常 pending状态下渲染fallback 当resolve...时重新render 遇到下一个异步请求重复上面操作 直到整个父组件抛出的promise对象都将resolve 将loading换成真正的组件 HOOK 钩子 HOOK提供了一系列函数式组件的钩子 const...从而界面得不到更新 为什么会产生:新的对象简单的引用了原始对象 改变了新的对象将影响到原始对象 如foo = {a: 1}  bar = foo  bar.a = 2这个时候区对比foo和bar是一样的...为什么使用异步处理?...setState不会立马改变React组件和state的值 setState通过触发一次组件的更新来引发重绘 多次setState函数调用产生的效果会合并 本文为作者原创,手码不易,允许转载,转载后请以链接形式说明文章出处

    92620
    领券