Docker 有啥优势?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker 有啥优势?相关的知识,希望对你有一定的参考价值。
1、更高效的利用系统资源docker对系统资源的利用率更高,无论是应用执行速度,内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机往往可以运行更多数量的应用。
2、更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而docker容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级,甚至毫秒级的启动时间,大大的节约了开发测试,部署的时间。
3、一致的运行环境
开发过程中常见的一个问题是环境一致问题,由于开发环境,测试环境,生产环境不一致,导致有些bug并未在开发过程中发现。而docker的镜像提供了除内核外完整的运行时环境,确保环境一致性,从而不会在出现“这段代码在我机器上没问题”这类问题。
4、持续支付和部署
对开发和运维人员来说,最希望就是一次创建和部署,可以在任意的地方运行。(定制应用镜像来实现集成、持续支付、部署。开发人员可以通过dockerfile来进行镜像构建,并结合持续集成系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署)。而且使用dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
5、更轻松的迁移
由于docker确保了执行环境的一致性,使得应用的迁移更加的容易。docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云、甚至是笔记本、其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
6、更轻松的维护和拓展
docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得十分简单。此外,docker团队同各个开源项目团队一起维护了一大批高质量的官网镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。 参考技术A 1.统一的管理服务;2.持续交付上的应用;3.弹性计算;想要了解更多,我推荐你去看看时速云,他们是一家全栈云原生技术服务提供商,提供云原生应用及数据平台产品,其中涵盖容器云PaaS、DevOps、微服务治理、服务网格、API网关等。大家可以去体验一下。 如果我的回答能够对您有帮助的话,求给大大的赞。
与 setState 回调相比,使用 componentDidUpdate 有啥优势?
【中文标题】与 setState 回调相比,使用 componentDidUpdate 有啥优势?【英文标题】:What is the advantage of using componentDidUpdate over the setState callback?与 setState 回调相比,使用 componentDidUpdate 有什么优势? 【发布时间】:2019-10-23 09:06:34 【问题描述】:为什么在 React 组件中使用 componentDidUpdate
比使用 setState
回调函数(可选的第二个参数)更推荐(如果需要同步 setState 行为)?
由于setState
是异步的,我正在考虑使用setState
回调函数(第二个参数)来确保代码在状态更新后执行,类似于then()
的承诺。特别是如果我需要在随后的 setState
调用之间重新渲染。
然而,官方 React Docs 说“setState() 的第二个参数是一个可选的回调函数,一旦 setState 完成并重新渲染组件就会执行。一般我们建议使用 componentDidUpdate() 来代替这种逻辑。” 这就是他们在那里所说的一切,所以看起来有点模糊。我想知道是否有更具体的原因建议不要使用它?如果可以的话,我会问 React 人自己。
如果我希望按顺序执行多个 setState 调用,就代码组织而言,setState 回调似乎比 componentDidUpdate 更好 - 回调代码是在 setState 调用中定义的。如果我使用 componentDidUpdate 我必须检查相关的状态变量是否发生了变化,并在那里定义后续代码,这不太容易跟踪。此外,在包含 setState 调用的函数中定义的变量将超出范围,除非我也将它们放入 state。
以下示例可能会显示何时使用 componentDidUpdate 可能会很棘手:
private functionInComponent = () =>
let someVariableBeforeSetStateCall;
... // operations done on someVariableBeforeSetStateCall, etc.
this.setState(
firstVariable: firstValue, , //firstVariable may or may not have been changed
() =>
let secondVariable = this.props.functionFromParentComponent();
secondVariable += someVariableBeforeSetStateCall;
this.setState( secondVariable: secondValue );
);
对
public componentDidUpdate(prevProps. prevState)
if (prevState.firstVariableWasSet !== this.state.firstVariableWasSet)
let secondVariable = this.props.functionFromParentComponent();
secondVariable += this.state.someVariableBeforeSetStateCall;
this.setState(
secondVariable: secondValue,
firstVariableWasSet: false,
);
private functionInComponent = () =>
let someVariableBeforeSetStateCall = this.state.someVariableBeforeSetStateCall;
... // operations done on someVariableBeforeSetStateCall, etc.
this.setState(
firstVariable: firstValue,
someVariableBeforeSetStateCall: someVariableBeforeSetStateCall,
firstVariableWasSet: true );
//firstVariable may or may not have been changed via input,
//now someVariableBeforeSetStateCall may or may not get updated at the same time
//as firstVariableWasSet or firstVariable due to async nature of setState
另外,除了一般推荐使用 componentDidUpdate 之外,在什么情况下 setState 回调更适合使用?
【问题讨论】:
组件可能会更新而不改变状态;你也有道具和背景。而setState
回调是一次性使用的回调。它会在应用此特定状态更改时通知您。
@Thomas 是的,如果我只想要一次性使用回调怎么办?我使用回调的主要原因是模拟同步代码,类似于 .then()
componentDidUpdate
每次需要重新渲染时都会调用,包括 props
更改
然后使用 setState 和更新函数而不是回调。 this.setState((state, props) => return counter: state.counter + props.step; );
。并且多个 setState 调用总是按顺序执行/应用,您不需要在回调中嵌套 setState
调用
@Thomas 在您引用的文档中也有一个回调。他没有谈论更新程序功能
【参考方案1】:
为什么比起
setState
回调函数更推荐使用componentDidUpdate
?
1。一致的逻辑
当使用setState()
的回调参数时,您可能会在不同的地方对setState()
进行两次单独的调用,它们都更新相同的状态,并且您必须记住在这两个地方使用相同的回调。
一个常见的例子是每当状态改变时调用第三方服务:
private method1(value)
this.setState( value , () =>
SomeAPI.gotNewValue(this.state.value);
);
private method2(newval)
this.setState( value ); // forgot callback?
这可能是一个逻辑错误,因为您可能想在值更改时调用服务。
这就是推荐componentDidUpdate()
的原因:
public componentDidUpdate(prevProps, prevState)
if (this.state.value !== prevState.value)
SomeAPI.gotNewValue(this.state.value);
private method1(value)
this.setState( value );
private method2(newval)
this.setState( value );
这样,服务保证在状态更新时被调用。
此外,状态可以从外部代码(例如 Redux)更新,您将没有机会为这些外部更新添加回调。
2。批量更新
setState()
的回调参数在组件重新渲染后执行。但是,由于批处理,不能保证多次调用 setState()
会导致多次渲染。
考虑这个组件:
class Foo extends React.Component
constructor(props)
super(props);
this.state = value: 0 ;
componentDidUpdate(prevProps, prevState)
console.log('componentDidUpdate: ' + this.state.value);
onClick = () =>
this.setState(
value: 7 ,
() => console.log('onClick: ' + this.state.value));
this.setState(
value: 42 ,
() => console.log('onClick: ' + this.state.value));
render()
return <button onClick=this.onClick>this.state.value</button>;
我们在onClick()
处理程序中有两个setState()
调用,每个调用都只是将新的状态值打印到控制台。
您可能希望onClick()
打印值7
,然后打印42
。但实际上,它会打印两次42
!这是因为这两个setState()
调用是批处理在一起的,只会导致一次渲染。
此外,我们还有一个componentDidUpdate()
,它也会打印新值。因为我们只发生了一次渲染,所以它只执行一次,并打印出值42
。
如果您希望与批量更新保持一致,通常使用componentDidMount()
会容易得多。
2.1。什么时候进行批处理?
没关系。
批处理是一种优化,因此您不应依赖批处理的发生或不发生。未来版本的 React 可能会在不同的场景中执行或多或少的批处理。
但是,如果您必须知道,在当前版本的 React (16.8.x) 中,批处理发生在异步用户事件处理程序(例如 onclick
)和 有时 生命周期方法中,如果 React控制执行。所有其他上下文从不使用批处理。
有关更多信息,请参阅此答案:https://***.com/a/48610973/640397
3。什么时候使用setState
回调更好?
当外部代码需要等待状态更新时,你应该使用setState
回调而不是componentDidUpdate
,并将其包装在一个promise中。
例如,假设我们有一个如下所示的Child
组件:
interface IProps
onClick: () => Promise<void>;
class Child extends React.Component<IProps>
private async click()
await this.props.onClick();
console.log('Parent notified of click');
render()
return <button onClick=this.click>click me</button>;
我们有一个Parent
组件,它必须在点击孩子时更新一些状态:
class Parent extends React.Component
constructor(props)
super(props);
this.state = clicked: false ;
private setClicked = (): Promise<void> =>
return new Promise((resolve) => this.setState( clicked: true , resolve));
render()
return <Child onClick=this.setClicked />;
在setClicked
中,我们必须创建一个Promise
来返回子级,唯一的方法是向setState
传递一个回调。
不可能在componentDidUpdate
中创建这个Promise
,但即使这样,由于批处理,它也无法正常工作。
杂项
由于
setState
是异步的,我正在考虑使用setState
回调函数(第二个参数)来确保在状态更新后执行代码,类似于.then()
的承诺。
setState()
的回调完全与 Promise 的工作方式不同,因此最好分开你的知识。
特别是如果我需要在随后的
setState
调用之间重新渲染。
为什么您需要在 setState()
调用之间重新渲染组件?
我能想象的唯一原因是父组件是否依赖于子 DOM 元素的某些信息,例如它的宽度或高度,并且父组件根据这些值在子组件上设置一些道具。
在您的示例中,您调用 this.props.functionFromParentComponent()
,它会返回一个值,然后您可以使用该值来计算某些状态。
首先,应该避免派生状态,因为记忆是一个更好的选择。但即便如此,为什么不让父级直接将值作为道具传递下去呢?那么你至少可以计算getDerivedStateFromProps()
中的状态值。
//firstVariable may or may not have been changed,
//now someVariableBeforeSetStateCall may or may not get updated at the same time
//as firstVariableWasSet or firstVariable due to async nature of setState
这些 cmets 对我来说没有多大意义。 setState()
的异步特性并不意味着状态没有得到正确更新。代码应该按预期工作。
【讨论】:
以上是关于Docker 有啥优势?的主要内容,如果未能解决你的问题,请参考以下文章