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

网站推广策划书包括哪些点网络营销推广方法和应用场景

网站推广策划书包括哪些点,网络营销推广方法和应用场景,cmd iis重启单个网站,wordpress 直播插件renderRoot的错误处理 1 #xff09;概述 在 completeWork这个方法之后, 再次回到 renderRoot 里面在 renderRoot 里面执行了 workLoop, 之后#xff0c;对 workLoop 使用了try catch如果在里面有任何一个节点在更新的过程当中 throw Error 都会被catch到catch到之后就是错误…renderRoot的错误处理 1 概述 在 completeWork这个方法之后, 再次回到 renderRoot 里面在 renderRoot 里面执行了 workLoop, 之后对 workLoop 使用了try catch如果在里面有任何一个节点在更新的过程当中 throw Error 都会被catch到catch到之后就是错误处理 给报错节点增加 incomplete 副作用 incomplete 的副作用在 completeUnitOfWork 的时候用来进行判断是要调用 completeWork还是调用 unwindWork 需要给父链上具有 error boundary 的节点增加副作用 让它去收集错误以及进行一定的处理 还需要创建错误相关的更新 2 源码 定位到 packages/react-reconciler/src/ReactFiberScheduler.js#L1293 在 renderRoot 里面的 do while 循环中 do {try {workLoop(isYieldy);// 在catch里面得到了一个 thrownValue, 这是一个error} catch (thrownValue) {resetContextDependences();resetHooks();// Reset in case completion throws.// This is only used in DEV and when replaying is on.let mayReplay;if (__DEV__ replayFailedUnitOfWorkWithInvokeGuardedCallback) {mayReplay mayReplayFailedUnitOfWork;mayReplayFailedUnitOfWork true;}// 如果 nextUnitOfWork 等于 null这是一个不属于正常流程里面的一个情况// 因为 nextUnitOfWork 是我们在更新一个节点之前它是有值的更新// 更新节点之后它会被赋成一个新的值// 一般来说它不应该是会存在 nextUnitOfWork 是 null 的一个情况// 即便 throw error 了上一个 nextUnitOfWork 也没有主动去把它消除if (nextUnitOfWork null) {// This is a fatal error.// 为 null 这种情况被认为是一个致命的错误didFatal true;// 调用 onUncaughtError无法处理的错误被抛出了// 这个时候react是会直接中断渲染染流程onUncaughtError(thrownValue);} else {// 非上述致命错误if (enableProfilerTimer nextUnitOfWork.mode ProfileMode) {// Record the time spent rendering before an error was thrown.// This avoids inaccurate Profiler durations in the case of a suspended render.stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);}if (__DEV__) {// Reset global debug state// We assume this is defined in DEV(resetCurrentlyProcessingQueue: any)();}if (__DEV__ replayFailedUnitOfWorkWithInvokeGuardedCallback) {if (mayReplay) {const failedUnitOfWork: Fiber nextUnitOfWork;replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);}}// TODO: we already know this isnt true in some cases.// At least this shows a nicer error message until we figure out the cause.// https://github.com/facebook/react/issues/12449#issuecomment-386727431invariant(nextUnitOfWork ! null,Failed to replay rendering after an error. This is likely caused by a bug in React. Please file an issue with a reproducing case to help us find it.,);const sourceFiber: Fiber nextUnitOfWork;let returnFiber sourceFiber.return;// 如果 returnFiber 等于 null, 说明这个错误是出现在更新 RootFiber 的过程当中// 那么 RootFiber 它是一个非常固定的节点就是说它没有用户代码去进行一个参与的// 如果这个它出现了一个错误也是一个致命的错误是一个react源码级的一个错误同上一样处理if (returnFiber null) {// This is the root. The root could capture its own errors. However,// we dont know if it errors before or after we pushed the host// context. This information is needed to avoid a stack mismatch.// Because were not sure, treat this as a fatal error. We could track// which phase it fails in, but doesnt seem worth it. At least// for now.didFatal true;onUncaughtError(thrownValue);} else {// 这里是常规处理错误throwException(root,returnFiber,sourceFiber,thrownValue,nextRenderExpirationTime,);// 立刻完成当前节点因为出错了子树渲染没有意义了nextUnitOfWork completeUnitOfWork(sourceFiber);continue;}}}break;} while (true);进入 onUncaughtError function onUncaughtError(error: mixed) {invariant(nextFlushedRoot ! null,Should be working on a root. This error is likely caused by a bug in React. Please file an issue.,);// Unschedule this root so we dont work on it again until theres// another update.// 这时候直接把 nextFlushedRoot 设置成 NoWork剩下的任务都不再执行了nextFlushedRoot.expirationTime NoWork;// 处理全局变量if (!hasUnhandledError) {hasUnhandledError true;unhandledError error;} }进入 throwException 这个是常规处理错误的处理器 function throwException(root: FiberRoot,returnFiber: Fiber,sourceFiber: Fiber,value: mixed,renderExpirationTime: ExpirationTime, ) {// 增加 Incomplete 这个 SideEffect// 这也是在 completeUnitOfWork 当中去判断节点是否有 Incomplete 的来源// 只有在这个节点throw了一个异常之后它才会被赋值 SideEffect// The source fiber did not complete.sourceFiber.effectTag | Incomplete;// Its effect list is no longer valid.// 对 firstEffect 和 lastEffect 置 null// 因为它已经抛出一个异常了子节点不会再进行渲染不会有effect的一个链sourceFiber.firstEffect sourceFiber.lastEffect null;// 这种就匹配 Promise对象或者 thenable 对象// 这个其实就对应 Suspense 相关的处理通过 throw 一个 thenable 的对象// 可以让这个组件变成一个挂起的状态等到这个 Promise 被 resolve之后再次进入一个正常的渲染周期// 这部分都是跟 Suspense 相关的代码先跳过if (value ! null typeof value object typeof value.then function) {// This is a thenable.const thenable: Thenable (value: any);// Find the earliest timeout threshold of all the placeholders in the// ancestor path. We could avoid this traversal by storing the thresholds on// the stack, but we choose not to because we only hit this path if were// IO-bound (i.e. if something suspends). Whereas the stack is used even in// the non-IO- bound case.let workInProgress returnFiber;let earliestTimeoutMs -1;let startTimeMs -1;do {if (workInProgress.tag SuspenseComponent) {const current workInProgress.alternate;if (current ! null) {const currentState: SuspenseState | null current.memoizedState;if (currentState ! null currentState.didTimeout) {// Reached a boundary that already timed out. Do not search// any further.const timedOutAt currentState.timedOutAt;startTimeMs expirationTimeToMs(timedOutAt);// Do not search any further.break;}}let timeoutPropMs workInProgress.pendingProps.maxDuration;if (typeof timeoutPropMs number) {if (timeoutPropMs 0) {earliestTimeoutMs 0;} else if (earliestTimeoutMs -1 ||timeoutPropMs earliestTimeoutMs) {earliestTimeoutMs timeoutPropMs;}}}workInProgress workInProgress.return;} while (workInProgress ! null);// Schedule the nearest Suspense to re-render the timed out view.workInProgress returnFiber;do {if (workInProgress.tag SuspenseComponent shouldCaptureSuspense(workInProgress.alternate, workInProgress)) {// Found the nearest boundary.// If the boundary is not in concurrent mode, we should not suspend, and// likewise, when the promise resolves, we should ping synchronously.const pingTime (workInProgress.mode ConcurrentMode) NoEffect? Sync: renderExpirationTime;// Attach a listener to the promise to ping the root and retry.let onResolveOrReject retrySuspendedRoot.bind(null,root,workInProgress,sourceFiber,pingTime,);if (enableSchedulerTracing) {onResolveOrReject Schedule_tracing_wrap(onResolveOrReject);}thenable.then(onResolveOrReject, onResolveOrReject);// If the boundary is outside of concurrent mode, we should *not*// suspend the commit. Pretend as if the suspended component rendered// null and keep rendering. In the commit phase, well schedule a// subsequent synchronous update to re-render the Suspense.//// Note: It doesnt matter whether the component that suspended was// inside a concurrent mode tree. If the Suspense is outside of it, we// should *not* suspend the commit.if ((workInProgress.mode ConcurrentMode) NoEffect) {workInProgress.effectTag | CallbackEffect;// Unmount the source fibers childrenconst nextChildren null;reconcileChildren(sourceFiber.alternate,sourceFiber,nextChildren,renderExpirationTime,);sourceFiber.effectTag ~Incomplete;if (sourceFiber.tag ClassComponent) {// Were going to commit this fiber even though it didnt complete.// But we shouldnt call any lifecycle methods or callbacks. Remove// all lifecycle effect tags.sourceFiber.effectTag ~LifecycleEffectMask;const current sourceFiber.alternate;if (current null) {// This is a new mount. Change the tag so its not mistaken for a// completed component. For example, we should not call// componentWillUnmount if it is deleted.sourceFiber.tag IncompleteClassComponent;}}// Exit without suspending.return;}// Confirmed that the boundary is in a concurrent mode tree. Continue// with the normal suspend path.let absoluteTimeoutMs;if (earliestTimeoutMs -1) {// If no explicit threshold is given, default to an abitrarily large// value. The actual size doesnt matter because the threshold for the// whole tree will be clamped to the expiration time.absoluteTimeoutMs maxSigned31BitInt;} else {if (startTimeMs -1) {// This suspend happened outside of any already timed-out// placeholders. We dont know exactly when the update was// scheduled, but we can infer an approximate start time from the// expiration time. First, find the earliest uncommitted expiration// time in the tree, including work that is suspended. Then subtract// the offset used to compute an async updates expiration time.// This will cause high priority (interactive) work to expire// earlier than necessary, but we can account for this by adjusting// for the Just Noticeable Difference.const earliestExpirationTime findEarliestOutstandingPriorityLevel(root,renderExpirationTime,);const earliestExpirationTimeMs expirationTimeToMs(earliestExpirationTime,);startTimeMs earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;}absoluteTimeoutMs startTimeMs earliestTimeoutMs;}// Mark the earliest timeout in the suspended fibers ancestor path.// After completing the root, well take the largest of all the// suspended fibers timeouts and use it to compute a timeout for the// whole tree.renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);workInProgress.effectTag | ShouldCapture;workInProgress.expirationTime renderExpirationTime;return;}// This boundary already captured during this render. Continue to the next// boundary.workInProgress workInProgress.return;} while (workInProgress ! null);// No boundary was found. Fallthrough to error mode.value new Error(An update was suspended, but no placeholder UI was provided.,);}// We didnt find a boundary that could handle this type of exception. Start// over and traverse parent path again, this time treating the exception// as an error.// renderDidError 方法 就是设置全局变量 nextRenderDidError 为 truerenderDidError();// 返回错误调用信息字符串value createCapturedValue(value, sourceFiber);let workInProgress returnFiber;// 根据tag匹配处理程序do {// 它其实就是往上去找它要找到第一个可以处理错误的 class component // 来进行一个错误的update的一个创建并且让它入栈// 等后期在commit的时候可以进行一个调用// 如果都没有那么它会到 HostRoot 上面来进行处理错误// 因为 HostRoot 它相当于是一个内置的错误处理的方式// 也会创建对应的update然后进行一个入队列然后后续进行一个调用的过程// 这就是一个 throw exception对于错误处理的一个情况switch (workInProgress.tag) {case HostRoot: {const errorInfo value;workInProgress.effectTag | ShouldCapture;workInProgress.expirationTime renderExpirationTime;// 这个 update 类似于 setState 创建的对象const update createRootErrorUpdate(workInProgress,errorInfo,renderExpirationTime,);enqueueCapturedUpdate(workInProgress, update);return;}// case ClassComponent:// Capture and retryconst errorInfo value;const ctor workInProgress.type;const instance workInProgress.stateNode;// 它要先去判断一下它现在没有 DidCapture 这个 SideEffect// 并且它是有 getDerivedStateFromError 这么一个方法// 或者它是有 componentDidCatch 生命周期方法if ((workInProgress.effectTag DidCapture) NoEffect (typeof ctor.getDerivedStateFromError function ||(instance ! null typeof instance.componentDidCatch function !isAlreadyFailedLegacyErrorBoundary(instance)))) {// 在这种情况下我们就可以给它加上 ShouldCapture 这个 SideEffect// 并且呢设置它的 expirationTime 等于 renderExpirationTime// 因为我要去对这个组件, 在这个周期里面进行一个更新的过程// 然后他也要去创建一个update调用的是 createClassErrorUpdateworkInProgress.effectTag | ShouldCapture;workInProgress.expirationTime renderExpirationTime;// Schedule the error boundary to re-render using updated stateconst update createClassErrorUpdate(workInProgress,errorInfo,renderExpirationTime,);enqueueCapturedUpdate(workInProgress, update);return;}break;default:break;}workInProgress workInProgress.return;} while (workInProgress ! null); }进入 renderDidError// packages/react-reconciler/src/ReactFiberScheduler.js function renderDidError() {nextRenderDidError true; }进入 createCapturedValue// packages/react-reconciler/src/ReactCapturedValue.js export function createCapturedValueT(value: T,source: Fiber, ): CapturedValueT {// If the value is an error, call this function immediately after it is thrown// so the stack is accurate.return {value,source,stack: getStackByFiberInDevAndProd(source),}; }进入 getStackByFiberInDevAndProdfunction describeFiber(fiber: Fiber): string {switch (fiber.tag) {case IndeterminateComponent:case LazyComponent:case FunctionComponent:case ClassComponent:case HostComponent:case Mode:const owner fiber._debugOwner;const source fiber._debugSource;const name getComponentName(fiber.type);let ownerName null;if (owner) {ownerName getComponentName(owner.type);}return describeComponentFrame(name, source, ownerName);default:return ;} }// 类似于js里面的error对象它会有一个stack的信息 // 就是哪个文件或者哪个方法调用的时候它出现了错误并且附上文件对应的代码的行数之类的信息 export function getStackByFiberInDevAndProd(workInProgress: Fiber): string {let info ;let node workInProgress;// 形成一个错误调用信息的过程do {info describeFiber(node);node node.return;} while (node);return info; }进入 createRootErrorUpdatefunction createRootErrorUpdate(fiber: Fiber,errorInfo: CapturedValuemixed,expirationTime: ExpirationTime, ): Updatemixed {const update createUpdate(expirationTime);// Unmount the root by rendering null.update.tag CaptureUpdate;// Caution: React DevTools currently depends on this property// being called element.update.payload {element: null};const error errorInfo.value;update.callback () {// 打印 erroronUncaughtError(error);logError(fiber, errorInfo);};return update; }进入 enqueueCapturedUpdate// 没有则创建有则克隆 // 挂载 update export function enqueueCapturedUpdateState(workInProgress: Fiber,update: UpdateState, ) {// Captured updates go into a separate list, and only on the work-in-// progress queue.let workInProgressQueue workInProgress.updateQueue;if (workInProgressQueue null) {workInProgressQueue workInProgress.updateQueue createUpdateQueue(workInProgress.memoizedState,);} else {// TODO: I put this here rather than createWorkInProgress so that we dont// clone the queue unnecessarily. Theres probably a better way to// structure this.workInProgressQueue ensureWorkInProgressQueueIsAClone(workInProgress,workInProgressQueue,);}// Append the update to the end of the list.if (workInProgressQueue.lastCapturedUpdate null) {// This is the first render phase updateworkInProgressQueue.firstCapturedUpdate workInProgressQueue.lastCapturedUpdate update;} else {workInProgressQueue.lastCapturedUpdate.next update;workInProgressQueue.lastCapturedUpdate update;} }进入 createClassErrorUpdatefunction createClassErrorUpdate(fiber: Fiber,errorInfo: CapturedValuemixed,expirationTime: ExpirationTime, ): Updatemixed {// 创建 updateconst update createUpdate(expirationTime);// 标记 tagupdate.tag CaptureUpdate;const getDerivedStateFromError fiber.type.getDerivedStateFromError;// 存在 getDerivedStateFromError 则作为 payload 回调处理if (typeof getDerivedStateFromError function) {const error errorInfo.value;update.payload () {return getDerivedStateFromError(error);};}const inst fiber.stateNode;if (inst ! null typeof inst.componentDidCatch function) {// 这个有组件错误被捕获之后它会向上去找有能够处理捕获错误信息的这个class component 来处理// 如果都没有它才会到 root 上面来进行一个处理// 它会根据像 getDerivedStateFromError 以及 componentDidCatch 这些生命周期方法来进行一个处理// 如果都没有这个指定那么这个classcomponent 是没有一个错误处理的功能的// 如果有就会对应的进行这些操作来进行一个调用update.callback function callback() {if (typeof getDerivedStateFromError ! function) {// To preserve the preexisting retry behavior of error boundaries,// we keep track of which ones already failed during this batch.// This gets reset before we yield back to the browser.// TODO: Warn in strict mode if getDerivedStateFromError is// not defined.markLegacyErrorBoundaryAsFailed(this);}const error errorInfo.value;const stack errorInfo.stack;// 输出 errorlogError(fiber, errorInfo);// 调用catch回调钩子 传入 stackthis.componentDidCatch(error, {componentStack: stack ! null ? stack : ,});if (__DEV__) {if (typeof getDerivedStateFromError ! function) {// If componentDidCatch is the only error boundary method defined,// then it needs to call setState to recover from errors.// If no state update is scheduled then the boundary will swallow the error.warningWithoutStack(fiber.expirationTime Sync,%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.,getComponentName(fiber.type) || Unknown,);}}};}return update; }经过以上的处理在调用了所有 exception 之后最后 立马调用了 completeUnitOfWork 这就说明这个节点报错了这个节点已经完成了它不会再继续去渲染它的子节点了 因为这个节点它已经出错了再渲染它的子节点是没有任何意义 所以在这里面如果有一个节点出错了就会立马对它执行 completeUnitOfWork 它走的就是 unwindWork 的流程了, 这个后续来看
http://www.dnsts.com.cn/news/53631.html

相关文章:

  • 深圳自助企业建站模版郑州建网站哪家好
  • 湖北公司网站备案严格吗英语网站海报手抄报怎么做
  • 做网站设像素做的比较好的购物网站
  • 北京网站建设及app设计师入驻平台
  • 网站字体使用沧州公司官网制作
  • 多种网站网站建设医药
  • 做h5的网站哪个好门户站模板
  • 网站开发+百度编辑器论坛型网站开发
  • 徐州做网站哪家好做wow宏的网站
  • 青岛网站设计品牌企业微网站模板源代码
  • 设计师网上接单的网站企业网页界面设计
  • 淘宝网站推广策划方案广州公司注册多久时间
  • 邮箱检测网站wordpress图片清理插件下载
  • 织梦模板大气网站建设类网站模板下载网站源代码生成网站
  • 学校如何报销网站开发费用html编辑器的特点
  • 学做网站基础知识网站建设平台官网要点有哪些
  • 东莞多语言网站建设微网站开发微网站建设
  • 昆山网站建设及推广平台公司债务风险
  • 提供邢台做wap网站开发网站需要用到的专业技术知识
  • 阿里云空间部署网站网站关键词 提醒
  • 网站动态和静态网和网站的区别
  • 免费网站安全软件下载安装品牌建设书籍
  • 禹城做网站的公司做网站有软件吗
  • 网站主机测速如何宣传推广自己的店铺
  • 娄底网站优化ss网站模板免费下载
  • 视频素材网站建设职业生涯规划大赛成长赛道
  • 深圳微商城网站制作公司青海汽车网站建设
  • 安徽省网站备案快吗迁西县住房和城乡规划建设局网站
  • 配置网站开发环境天津网站开发建设公司
  • 赣榆城乡建设局网站怎么自己做网站的步骤