yuyingwu / blog Goto Github PK
View Code? Open in Web Editor NEWYuying Wu's Blog
Home Page: http://www.wuyuying.com/
License: MIT License
Yuying Wu's Blog
Home Page: http://www.wuyuying.com/
License: MIT License
前几天面试候选人的时候,有提到用React 16.x
重构了一个电商首页,对各个业务模块做更细颗粒拆解和代码组织,提升开发效率和降低维护成本,在这里要给小同学点个赞,有想法也有落地成果。后来问及“一个模块报错,搞挂了整个页面”的问题,大家都知道,如果页面的entry是index.js,在里面引入各个components的话,运行时只要有一行代码挂了,整个js都会挂掉。针对这个问题,除了前端同学的自测、QA同学的测试或者人肉的code review,有没有代码层面或者机制,做好模块间的错误隔离/处理/上报?比较遗憾的是,在生产环境下,候选人没有针对这个线上大流量页面做相关的处理,靠人肉规范,没能给出比较好的错误隔离的设计思路和实践方案。
其实相关的思路可以有很多种,模块/页面级的异常处理、commit前跑test case、提交后或者发布前headless检查页面报错,等等。
在代码异常处理上,一般我们会用try-catch来做:
try {
ReactDOM.render(<App />, document.getElementById('root'));
}
catch(error) {
console.error('Unknown error intercepted. error: ', error);
}
但可以发现,异常信息是捕获到了,但是代码运行就结束了,并没有从异常中“恢复”。
过去,组件内的 JavaScript 错误会导致 React 的内部状态被破坏,并且在下一次渲染时 产生 可能无法追踪的 错误。这些错误基本上是由较早的其他代码(非 React 组件代码)错误引起的,但 React 并没有提供一种在组件中优雅处理这些错误的方式,也无法从错误中恢复。
部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。
错误边界是一种 React 组件,这种组件可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且,它会渲染出备用 UI,而不是渲染那些崩溃了的子组件树。错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误。
笔者之前写过一篇《这!就是1688 PC首页》,里面有提到我们团队基于React 16.x的页面实践,一个 index.jsx 中引入子目录下的各种 components ,初期开发阶段,整个应用处于“裸奔”的状态,一个组件抛错误,整个页面都会挂掉。日常抛JS error的情况包括但不限于代码逻辑没注意写错了、数据接口挂了或者返回结构不如预期、多层数据获取的容错等。首页有19个组件和一些公用的函数,如果其中一处报错,会把整个页面搞挂,风险太大。最后选用了React 16的Error Boundaries(错误边界)API去做components之间的容错隔离/错误上报的。
在里面主要做几件事:
getDerivedStateFromError
,捕获运行时的异常,用一个state hasError
来标记当前组件是否报异常了,后续可以用这个state来控制展示传入还是降级的UI;componentDidCatch
,可以在里面放异常日志上传到服务器的逻辑,同时也支持自定义错误处理回调 this.props.errorHandler
;placeholder
从 this.props
传进来,支持自定义降级UI。由于异常发生后,我们对该组件可以是默认处理不展示,或者展示为开发者自定义的展示,所以这里开放了placeholder
支持自定义UI。import React from 'react';
import wpo from '@ali/retcodelog';
class ErrorBoundary extends React.Component {
static defaultProps = {
placeholder: null,
};
constructor(props) {
super(props);
this.state = {
hasError: false,
};
}
static getDerivedStateFromError() {
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}
componentDidCatch(error, info) {
// 自定义错误处理回调
const { errorHandler } = this.props;
errorHandler && errorHandler({ error, info });
// 错误日志上报到服务器
wpo.error('Error Handler', info &&
info.componentStack ?
info.componentStack :
'Unexpect error from Error Handler');
}
render() {
const { placeholder } = this.props;
const { hasError } = this.state;
// 异常发生后的自定义降级(恢复)UI
if (hasError) {
return placeholder;
}
let tpl = this.props.children;
return tpl;
}
}
export default ErrorBoundary;
一个应用中,可能会存在多个错误边界,如对整个应用App的全局错误边界,以及对每个模块使用的模块错误边界。
{/* global error boundary */}
<ErrorBoundary errorHandler={() => { window.location.href = 'https://1688.com' }}>
<App>
{/* category error boundary */}
<ErrorBoundary placeholder={<StaticCategory />}>
<Category />
</ErrorBoundary>
</App>
</ErrorBoundary>
全局或模块级错误边界可能看下图会更直观一些。
回到文章的一开头,很多时候,我们在日常开发中,会不断地往前冲,开发很多酷炫的交互或者功能,有时可能忘记停下来,把更多的目光在质量保障上,本文提到的React Error Boundaries只是其中一个小的点。不同的设备环境、网络环境、用户操作路径,会不会在你不知道的情况下,我们的页面“坏”了,还是需要把这些信息收集起来,让我们看到“想当然”以外更多的东西。
共勉~
值得注意的是,错误边界有一些无法捕获错误的场景:
事件处理
异步代码(如setTimeout
和requestAnimationFrame
回调函数)
服务端渲染
ErrorBoundary自身抛出的异常(并非来自子组件)
有什么想法,欢迎在这里交流哈 😄🎉
最近小伙伴们有在考虑换工作的事宜,我刚好看到这本《人人都有好工作》,里面有一章专门介绍哪些内容应该出现在简历中,而哪些不应该,摘录下来,共勉。
联系方式
职业自述
工作经历【详见这里】
教育背景
工作之外的其他相关成就(如果你觉得自己的工作经历还不够丰富)
关键词及技能列表
照片
职业目标,无意义
兴趣爱好
“如要求可提供相关证明”
无关的工作经验
在工作经验的部分,你所要着重阐述的是自己在某个领域工作了多少年,这个领域最好能具体到什么行业的哪一种工作,举个例子:
你需要在专业技能部分阐述自己的最高技能是什么,如果可能就加上量化的陈述。
也许你还有一些别的技能可以写进简历,当然那只是针对某家具体的公司。
公司行
职位,以及任职期间取得的成就
在说明中加上一些数字能起到锦上添花的作用。如果你能把创造的工作价值用数据量化,这也将给所出示的内容价值加分。即使这个项目并不是依靠你个人的力量完成,这依然体现了你自身参与的价值。(请确保你能在面试时将写在简历中的数据流畅的说出来,而不是支支吾吾)
将你的学习经历以及平时的兴趣爱好写进职业描述部分,然后加上一点你期望的发展方向。
开源软件不仅仅为互联网注入一股新鲜力量,它也可以成为职业生涯的爆发点,特别是对于一个职场新人来说。它能为刚开始找工作的你提供至关重要的工作经验以及工作样例。
着手一个开源软件(OSS)项目,无论这个项目是你自主开发的还是原本已有的,对你来说都是一份实实在在的工作经验。这既能显示你有编写代码的能力,又表明你能很好地和团队合作、与他人相处。而且,这些工作经历是雇主可以找到和验证的。
开源项目也让你能有真实技能范例可随时给别人展示。每次演讲会上,当我说到准备好一份相关工作成果去面试时,总能听到一些人的抱怨说:“我没法带工作样例去面试,因为那些代码都是归原公司所以没法随随便便示人。”这很糟糕,因为这样会让他们失去一些求职成功的机会。而开源软件项目就是很理想的解决办法,你可以随时把你的绝活展示给大家。
你并不需要为开源软件做出特别突出的贡献,而且你能做的也不一定非得是写代码。你也可以贡献文档,为维基百科的某一个条目添加文章,或者仅仅在自己参与的邮件群组中回答他人提出的问题。关键只是你用一种可以证明自己的方式为一些实际编程项目贡献力量。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.