当前位置: 首页 > news >正文

网站建设常州天堂在线资源种子

网站建设常州,天堂在线资源种子,网络直播营销的方式有哪些,wordpress 微博 主题本文内容均针对于18.x以下版本 setState 到底是同步还是异步?很多人可能都有这种经历,面试的时候面试官给了你一段代码,让你说出输出的内容,比如这样: constructor(props) {super(props);this.state {val: 0}}compo…

本文内容均针对于18.x以下版本

setState 到底是同步还是异步?很多人可能都有这种经历,面试的时候面试官给了你一段代码,让你说出输出的内容,比如这样:

constructor(props) {super(props);this.state = {val: '0'}}componentDidMount() {this.setState({data: '1'})console.log("val: ", this.state.val);// val: 0setTimeout(() => {this.setState({data: '2'})console.log("setTimeout ", this.state.val);//val:2})}

 而这段代码的输出结果,第一个 console.log 会输出0 ,而第二个 console.log 会输出2 。也就是第一次 setState 的时候,它是异步的,第二次 setState 的时候,它又变成了同步的。

这是为什么呢?

只要你进入了 react 的调度流程,那就是异步的。只要你没有进入 react 的调度流程,那就是同步的。什么东西不会进入 react 的调度流程? setTimeout setInterval ,直接在 DOM 上绑定原生事件等。这些都不会走 React 的调度流程,你在这种情况下调用 setState ,那这次 setState 就是同步的。 否则就是异步的。

而 setState 同步执行的情况下, DOM 也会被同步更新,也就意味着如果你多次 setState ,会导致多次更新,这是毫无意义并且浪费性能的。

 setState 被调用后最终会走到 scheduleUpdateOnFiber 这个函数里面来,下面是源码:

function scheduleUpdateOnFiber(fiber, expirationTime) {checkForNestedUpdates();warnAboutRenderPhaseUpdatesInDEV(fiber);var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);if (root === null) {warnAboutUpdateOnUnmountedFiberInDEV(fiber);return;}checkForInterruption(fiber, expirationTime);recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the// priority as an argument to that function and this one.var priorityLevel = getCurrentPriorityLevel();if (expirationTime === Sync) {if ( // Check if we're inside unbatchedUpdates(executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering(executionContext & (RenderContext | CommitContext)) === NoContext) {// Register pending interactions on the root to avoid losing traced interaction data.schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed// root inside of batchedUpdates should be synchronous, but layout updates// should be deferred until the end of the batch.performSyncWorkOnRoot(root);} else {ensureRootIsScheduled(root);schedulePendingInteractions(root, expirationTime);// 重点!!!!!!if (executionContext === NoContext) {// Flush the synchronous work now, unless we're already working or inside// a batch. This is intentionally inside scheduleUpdateOnFiber instead of// scheduleCallbackForFiber to preserve the ability to schedule a callback// without immediately flushing it. We only do this for user-initiated// updates, to preserve historical behavior of legacy mode.flushSyncCallbackQueue();}}} else {ensureRootIsScheduled(root);schedulePendingInteractions(root, expirationTime);}if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered// discrete, even inside a discrete event.priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority)) {// This is the result of a discrete event. Track the lowest priority// discrete update per root so we can flush them early, if needed.if (rootsWithPendingDiscreteUpdates === null) {rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);} else {var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {rootsWithPendingDiscreteUpdates.set(root, expirationTime);}}}
}

我们着重看这段代码:

if (executionContext === NoContext) {// Flush the synchronous work now, unless we're already working or inside// a batch. This is intentionally inside scheduleUpdateOnFiber instead of// scheduleCallbackForFiber to preserve the ability to schedule a callback// without immediately flushing it. We only do this for user-initiated// updates, to preserve historical behavior of legacy mode.flushSyncCallbackQueue();
}

executionContext 代表了目前 react 所处的阶段,而 NoContext 你可以理解为是 react 已经没活干了的状态。而 flushSyncCallbackQueue 里面就会去同步调用我们的 this.setState ,也就是说会同步更新我们的 state 。所以,我们知道了,当 executionContext 为 NoContext 的时候,我们的 setState 就是同步的。那什么地方会改变 executionContext 的值呢?

我们随便找几个地方看看

function batchedEventUpdates$1(fn, a) {var prevExecutionContext = executionContext;executionContext |= EventContext;...省略
}function batchedUpdates$1(fn, a) {var prevExecutionContext = executionContext;executionContext |= BatchedContext;...省略
}

当 react 进入它自己的调度步骤时,会给这个 executionContext 赋予不同的值,表示不同的操作以及当前所处的状态,而 executionContext 的初始值就是 NoContext ,所以只要你不进入 react 的调度流程,这个值就是 NoContext ,那你的 setState 就是同步的。

http://www.yayakq.cn/news/151190/

相关文章:

  • 中小企业建站是什么无锡网站制作多少钱
  • flash使用教程信息流广告优化师
  • 示范高职建设网站厦门外贸推广
  • 专业网站建设团队网站建设分解结构
  • 网站开发分层岳阳网站推广
  • 分类目录网站怎么做做网站的收费标准
  • 天津餐饮网站建设龙海做网站费用
  • 厦门跨境建站平台网站建设招标流程
  • 怎么创建视频网站邀请注册推广赚钱的app
  • 做网站模板哪里买平舆专业网站建设
  • 打开网站出现directory餐饮营销引流都有什么方法
  • 简单网站建设方案wordpress应用教程
  • 做网站麻烦么注册网站地址第1行第二行怎么填
  • 自建站价格八八网络科技有限公司
  • 网站建设河南青岛网站建设公司招聘
  • 网站建设找哪里电子商务网站课程设计总结
  • 做网站 编程语言网站开发如何验证
  • 企业网站建设好的例子网络营销该如何发展
  • 青海省公路建设市场信用信息服务网站深圳为华网络科技有限公司
  • 嘉兴做网站美工的工作中国甘肃网
  • 企业网络营销站点的功能有哪些长沙h5建站
  • 常宁网站开发抖音广告投放平台官网
  • 上海机械网站建设制作app软件需要用到哪些技术
  • 嘉兴网站建设制作宁波网站扔优化
  • 优秀网站设计作品分析绵阳网络推广公司
  • 哪个网站做简历免费做销售有什么技巧和方法
  • 知名的设计网站网络规划设计师知识点
  • 免费建网站视频教程python做网站安全性
  • 企业做网站的注意什么问题优化服务质量
  • 弹幕做的视频网站中信建设有限公司是央企吗