Comments (31)
这里所说的同步异步, 并不是真正的同步异步, 它还是同步执行的。
这里的异步指的是多个state会合成到一起进行批量更新。
希望初学者不要被误导
from daily-interview-question.
setState是同步还是异步?
基于当前最新稳定版本v16.14.0进行分析
此处同步异步
的定义
我们知道Promise.then()
,setTimeout
是异步执行. 从js执行来说, setState
肯定是同步执行.
所以这里讨论的同步和异步并不是指setState
是否异步执行, 而是指调用setState
之后this.state
能否立即更新.
分析
- 众所周知调用
setState({item: 'new xxx'})
之后, 会将传入setState
的参数包装成一个update对象
并添加到updateQueue
队列中. - 之后
updateQueue
队列在什么时机被合并到this.state
中才是本题目的关键. 因为合并之后this.state
必然就已经更新了. - state的合并是在fiber构建循环中进行的, 而fiber构建循环必然是在触发scheduler调度之后进行. 关于这一点的详细论述可以参考react两大工作循环.
到这里问题转化为调用setState
之后, 是否立即触发scheduler调度?
- 如果立即进行scheduler调度, 那么
this.state
必然能同步获取. - 反之, 如果异步进行scheduler调度, 那么
this.state
不能同步获取.
- 每次调用
setState
都会进行一次scheduler调度(可以参考React 调度机制).
在最新源码v16.14.0中体现为调用ensureRootIsScheduled
. 在该源码中, 可以得到回答本题目的最佳答案, 核心逻辑如下:
if (
(executionContext & LegacyUnbatchedContext) !== NoContext &&
(executionContext & (RenderContext | CommitContext)) === NoContext
) {
// .... 省略部分本次讨论不会涉及的代码
} else {
ensureRootIsScheduled(root, eventTime); // 触发scheduler调度(调度是异步的) , 所以该函数不会立即触发render.
if (executionContext === NoContext) { // 当执行上下文为0时, 会刷新同步队列
// .... 省略部分本次讨论不会涉及的代码
// 这里是关键, 执行同步回调队列. 有兴趣的同学可以继续在源码中查看, 可以得到结论:
// if分支之外的ensureRootIsScheduled(root, eventTime)和此处的flushSyncCallbackQueue()
// 最终都是调用performSyncWorkOnRoot进行fiber树的循环构建
flushSyncCallbackQueue();
}
}
结论
- 如楼上 @taichiyi 所述, setState是同步和异步最关键的因素是react内部的执行上下文
executionContext
的状态.
- 当
executionContext
为空时, 表现为同步. - 反之
executionContext
不为空, 表现为异步.
executionContext
何时为空?
这个问题反过来更好理解, 什么时候executionContext
不为空? 因为executionContext
是react内部控制的属性, 当初次render, 合成事件触发时都会改变executionContext
的值.
- 只要绕开react内部触发更改
executionContext
的逻辑, 就能保证executionContext
为空, 进而实现setState
为同步.
- 可以使用异步调用如setTimeout, Promise, MessageChannel等
- 可以监听原生事件, 注意不是合成事件(合成事件是react体系, 会更改
executionContext
), 在原生事件的回调函数中执行 setState 就是同步的
附加条件
以上分析都是基于legacy
模式进行分析的, 众所周知react即将(可能)全面进入concurrent
模式(可以参考react 启动模式). 在concurrent
模式下, 这个题目可能就没有意义了, 因为从目前最新代码来看, 在concurrent
模式下根本就不会判断executionContext
, 所以concurrent
模式下setState都为异步.
// concurrent模式下根本没有下列代码, 所以不可能同步
if (executionContext === NoContext) {
flushSyncCallbackQueue();
}
演示示例
对于此问题在codesandbox上面做了一个demo(详细演示示例). 在legacy
和concurrent
模式下演示并验证了上述结论.
from daily-interview-question.
React的setState本身并不是异步的,是因为其批处理机制给人一种异步的假象。
【React的更新机制】
生命周期函数和合成事件中:
- 无论调用多少次setState,都不会立即执行更新。而是将要更新的state存入'_pendingStateQuene',将要更新的组件存入'dirtyComponent';
- 当根组件didMount后,批处理机制更新为false。此时再取出'_pendingStateQuene'和'dirtyComponent'中的state和组件进行合并更新;
原生事件和异步代码中:
- 原生事件不会触发react的批处理机制,因而调用setState会直接更新;
- 异步代码中调用setState,由于js的异步处理机制,异步代码会暂存,等待同步代码执行完毕再执行,此时react的批处理机制已经结束,因而直接更新。
总结:
react会表现出同步和异步的现象,但本质上是同步的,是其批处理机制造成了一种异步的假象。(其实完全可以在开发过程中,在合成事件和生命周期函数里,完全可以将其视为异步)
from daily-interview-question.
我的个人观点是这样的对于同步或者是异步都可以进行控制的想要同步就同步想要异步就异步
我老婆提醒我如果面试官问什么你管不了 谁让你想去那工作呢
from daily-interview-question.
由React控制的事件处理程序,以及生命周期函数调用setState不会同步更新state 。
React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等。
from daily-interview-question.
react 18 发布之后,估计要对不同版本不同模式进行不同的回答了
from daily-interview-question.
异步更新,同步执行
from daily-interview-question.
(微医)React 中 setState 什么时候是同步的,什么时候是异步的?
【高能预警:你懂得越多,你不懂得更多】
-
4. 基础篇-玄学state:在不同的执行环境下,或者不同的 React 模式下,State 更新流程都是不同的
-
React 是有多种模式的,基本平时用的都是 legacy 模式
- 除了 legacy 模式,还有 blocking 模式和 concurrent 模式 —— blocking 可以视为 concurrent 的优雅降级版本和过渡版本,React 最终目的,不久的将来将以 concurrent 模式作为默认版本,这个模式下会开启一些新功能
- React V18 版本,concurrent 将作为一个稳定的功能出现
1. legacy
模式下的 setState
1.1 React 在触发 setState 时主要做了哪些事:
- 首先,setState 会产生当前更新的优先级(老版本用 expirationTime,新版本用 lane)
- 接下来 React 会从 fiber Root 根部 fiber 向下调和子节点,调和阶段将对比发生更新的地方,更新对比 expirationTime,找到发生更新的组件,合并 state,然后触发 render 函数,得到新的 UI 视图层,完成 render
- 接下来来到 commit 阶段,替换真实 DOM,完成此次更新流程,最后会执行 setState 中 callback 函数,到此为止完成了一次 setState 全过程
一个主要任务的先后顺序:render 阶段 render 函数执行 -> commit 阶段真实 DOM 替换 -> setState 回调函数执行 callback
1.2 类组件 setState 原理揭秘:
-
类组件初始化过程中绑定了负责更新的
Updater
对象,调用 setState,实际上是 React 底层调用 Updater 对象上的enqueueSetState
方法// react-reconciler/src/ReactFiberClassComponent.js enqueueSetState(){ /* 每一次调用`setState`,react 都会创建一个 update 里面保存了 */ const update = createUpdate(expirationTime, suspenseConfig); /* callback 可以理解为 setState 回调函数,第二个参数 */ callback && (update.callback = callback) /* enqueueUpdate 把当前的update 传入当前fiber,待更新队列中 */ enqueueUpdate(fiber, update); /* 开始调度更新 */ scheduleUpdateOnFiber(fiber, expirationTime); }
enqueueSetState
会创建一个 update,然后放入当前 fiber 对象的待更新队列中,最后开启调度更新,进入到(批量)更新流程 -
React 批量更新:
// react-dom/src/events/DOMLegacyEventPluginSystem.js /* 在`legacy`模式下,所有的事件都将经过此函数同一处理 */ function dispatchEventForLegacyPluginEventSystem(){ // handleTopLevel 事件处理函数 batchedEventUpdates(handleTopLevel, bookKeeping); }
// react-dom/src/events/ReactDOMUpdateBatching.js function batchedEventUpdates(fn,a){ /* 开启批量更新 */ isBatchingEventUpdates = true; try { /* 这里执行了的事件处理函数, 比如在一次点击事件中触发setState,那么它将在这个函数内执行 */ return batchedEventUpdatesImpl(fn, a, b); } finally { /* try 里面 return 不会影响 finally 执行 */ /* 完成一次事件,批量更新 */ isBatchingEventUpdates = false; } }
- 在 React 事件执行之前通过
isBatchingEventUpdates = true
打开开关,开启事件批量更新,当该事件结束,再通过isBatchingEventUpdates = false
关闭开关,然后在·scheduleUpdateOnFiber `中根据这个开关来确定是否进行批量更新
export default class index extends React.Component{ state = { number:0 } handleClick= () => { this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback1', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback2', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback3', this.state.number) }) console.log(this.state.number) } render(){ return <div> { this.state.number } <button onClick={ this.handleClick } >number++</button> </div> } }
0, 0, 0, callback1 1 ,callback2 1 ,callback3 1
- 在 React 事件执行之前通过
-
异步操作(promise 或者 setTimeout)打破批量更新规则:
- setTimeout 中的 setState 为什么会多次 render?
- 因为异步出了事件系统的执行上下文:触发时 isBatchingUpdates 为 false,所以多次 setState 没有被合并处理,能够直接进行更新
setTimeout(()=>{ this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback1', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback2', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback3', this.state.number) }) console.log(this.state.number) })
callback1 1 , 1, callback2 2 , 2,callback3 3 , 3
- setTimeout 中的 setState 为什么会多次 render?
-
异步环境继续开启批量更新模式:
React-Dom 中提供了批量更新方法
unstable_batchedUpdates
,可以去手动批量更新import ReactDOM from 'react-dom' const { unstable_batchedUpdates } = ReactDOM setTimeout(()=>{ unstable_batchedUpdates(()=>{ this.setState({ number:this.state.number + 1 }) console.log(this.state.number) this.setState({ number:this.state.number + 1}) console.log(this.state.number) this.setState({ number:this.state.number + 1 }) console.log(this.state.number) }) })
0 , 0 , 0 , callback1 1 , callback2 1 ,callback3 1
在实际工作中,
unstable_batchedUpdates
可以用于 Ajax 数据交互之后,合并多次 setState,或者时多次 useState —— 如果批量更新处理,一次数据交互多次改变 state 会促使视图多次渲染 -
提升更新优先级:
React-dom 提供了 flushSync ,flushSync 可以将回调函数中的更新任务,放在一个较高的优先级中
handerClick=()=>{ setTimeout(()=>{ this.setState({ number: 1 }) }) this.setState({ number: 2 }) ReactDOM.flushSync(()=>{ this.setState({ number: 3 }) }) this.setState({ number: 4 }) } render(){ console.log(this.state.number) return ... }
3 4 1
首先
flushSync
this.setState({ number: 3 })
设定了一个高优先级的更新,然后 2 和 3 被批量更新到 3,最后更新 setTimeout 中的 1flushSync 中的 setState > 正常执行上下文中的 setState > setTimeout、Promise 中的 setState
1.3 函数组件 useState 原理揭秘
(未完待下一道面试题)18. 原理篇-hooks原理
2. V18concurrent
模式下的 setState
(未完待下一道面试题)34. v18特性篇-concurrent 下的 state更新流程
from daily-interview-question.
先说结论:
如果是通过 DOM 事件
(例如:onClick) 的事件处理函数
调用了 setState 函数,导致 React 进行更新(或者说“调度”scheduleWork),则此时事件处理函数
中的 setState 的行为是异步的(也就是合并更新)。
上面的评论中说了很多 setState “异步”的情况。我这里补充一下“同步”的情况,下面的例子使用了 setTimeOut,组件最后显示结果是33
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.handleAddCount = this.handleAddCount.bind(this);
}
componentDidMount() {
setTimeout(this.handleAddCount, 1*1000);
}
handleAddCount() {
this.setState({
count: this.state.count + 11
});
this.setState({
count: this.state.count + 22
});
}
render() {
return <div>{this.state.count}</div>;
}
}
源码:
从源码的角度来说,setState 的行为是“异步”还是“同步”取决于 React 执行 setState 方法时的执行上下文
①(ExecutionContext)。
如果 ExecutionContext 为 0,表示当前没有正在进行的其他任务,则 setState 是“同步”的。React 源码地址:https://github.com/facebook/react/blob/b53ea6ca05d2ccb9950b40b33f74dfee0421d872/packages/react-reconciler/src/ReactFiberWorkLoop.js#L411
①注意这里的执行上下文
不是浏览器的,为了更好的控制渲染任务,避免长时间占用浏览器的主线程, React 实现了自己的执行上下文
。
from daily-interview-question.
React Dan Abramov 大佬的解释
这题应该是想问 setState
的 reconiliation 特性
from daily-interview-question.
这个issue之前是没问题的。React18后setState全部都是异步的,所以不需要再分情况讨论,包括原生DOM事件和setTimeout之类的。
另外我觉得讨论这个问题没多大意义,因为setState本身设计出来就是异步的,要同步的访问state就用第二个参数回调访问啊。不然别人设计出第二个参数干嘛。
- 面试应该问:为什么setState是异步的?
- 而不是问:什么情况是同步,什么情况是异步?
from daily-interview-question.
setState是异步的,setState之后,取state中的值并不一定是最新更新的值。
这样设计的原因是可能在同步的代码中可能存在连续的多个setSate操作,react会对他们进行智能的合并,直到执行到了最后一个setState,React才回智能的合并state的,并异步的设置state的值,后续判断是否进行render操作.如果同步的每次setState都去走一遍reconciler & commit操作,则太耗性能了
from daily-interview-question.
在最新的版本里面,React已经默认auto batch updating了
from daily-interview-question.
在最新的版本里面,React已经默认auto batch updating了
针对这个问题,大家默认讨论版本是react15, fiber之前
from daily-interview-question.
如果setState 在React 能够控制的范围被调用,它就是异步的。 例如:合成事件处理函数, 生命周期函数, 此时会进行批量更新, 也就是将状态合并后再进行DOM 更新。 如果setState 在原生JavaScript 控制的范围被调用,它就是同步的
from daily-interview-question.
这里所说的同步异步, 并不是真正的同步异步, 它还是同步执行的。
这里的异步指的是多个state会合成到一起进行批量更新。
希望初学者不要被误导你的说法还是太片面了,可以看下官网的介绍
https://reactjs.org/docs/faq-state.html#when-is-setstate-asynchronous
你是想说明什么,没太明白。
你的意思难道是从你截图给的这个可以看出reactsetState是或者部分是异步的?
---补充---
或者你的意思难道是标题是《何时setState是异步的》, 就断定 “setState确实可能是异步的”
from daily-interview-question.
这道题和19题有些类似。#18 (comment)
from daily-interview-question.
我们平时写的时候就当它是异步进行就好了。
from daily-interview-question.
@yygmind 被这问题吓到了,还好点进来看了,你做出了我放心的解释
from daily-interview-question.
单独的说同步异步没有意义,一般配合场景:setState后取值
使用的,初学者经常发现setState后值还是旧的,而且这个错误很难发现。
from daily-interview-question.
我们知道Promise.then(),setTimeout是异步执行. 从js执行来说, setState肯定是同步执行.
所以这里讨论的同步和异步并不是指setState是否异步执行, 而是指调用setState之后this.state能否立即更新.
from daily-interview-question.
为什么setTimeout里面的setState就不能进行批处理?如果批处理会有什么异常,望解答。
from daily-interview-question.
isBatchingUpdates = true
setTimeout(() => {
this.setState({
count: this.state.count + 1
})
}, 0)
isBatchingUpdates = false
看了这段应该就清晰很多了。 react 会在执行前加一个“锁”来标记是否需要批处理, 如上,react加了锁之后立刻就释放了,然后才会执行setTimeout里的setState, 也就是说setTimeout和原生事件会脱离react的控制。 只有在react控制下才会存在批处理,setState才会有“异步”效果。
为什么setTimeout里面的setState就不能进行批处理?如果批处理会有什么异常,望解答。
from daily-interview-question.
isBatchingUpdates = true setTimeout(() => { this.setState({ count: this.state.count + 1 }) }, 0) isBatchingUpdates = false
看了这段应该就清晰很多了。 react 会在执行前加一个“锁”来标记是否需要批处理, 如上,react加了锁之后立刻就释放了,然后才会执行setTimeout里的setState, 也就是说setTimeout和原生事件会脱离react的控制。 只有在react控制下才会存在批处理,setState才会有“异步”效果。
为什么setTimeout里面的setState就不能进行批处理?如果批处理会有什么异常,望解答。
这里的 “控制” 是指什么呢?如果脱离控制后会发生什么呢?
from daily-interview-question.
setTimeout/setInterval调用并不是同步setState,也是异步的
在线例子:https://stackblitz.com/edit/react-ts-sqs8mw?file=App.tsx
from daily-interview-question.
from daily-interview-question.
@janyin clickHandler 是通过 react 合成事件调用的呀
from daily-interview-question.
Akarinx
是合成事件,但是里面用的是setTimeout
from daily-interview-question.
这个是原生事件的例子: https://stackblitz.com/edit/react-ts-kabj1e?file=index.tsx,App.tsx
@janyin clickHandler 是通过 react 合成事件调用的呀
from daily-interview-question.
这个是原生事件的例子: https://stackblitz.com/edit/react-ts-kabj1e?file=index.tsx,App.tsx
@janyin clickHandler 是通过 react 合成事件调用的呀
噢噢 是我这边的问题,确实是因为 react18 的问题
from daily-interview-question.
(微医)React 中 setState 什么时候是同步的,什么时候是异步的?
【高能预警:你懂得越多,你不懂得更多】
- 4. 基础篇-玄学state:在不同的执行环境下,或者不同的 React 模式下,State 更新流程都是不同的
- React 是有多种模式的,基本平时用的都是 legacy 模式
- 除了 legacy 模式,还有 blocking 模式和 concurrent 模式 —— blocking 可以视为 concurrent 的优雅降级版本和过渡版本,React 最终目的,不久的将来将以 concurrent 模式作为默认版本,这个模式下会开启一些新功能
- React V18 版本,concurrent 将作为一个稳定的功能出现
1.
legacy
模式下的 setState1.1 React 在触发 setState 时主要做了哪些事:
- 首先,setState 会产生当前更新的优先级(老版本用 expirationTime,新版本用 lane)
- 接下来 React 会从 fiber Root 根部 fiber 向下调和子节点,调和阶段将对比发生更新的地方,更新对比 expirationTime,找到发生更新的组件,合并 state,然后触发 render 函数,得到新的 UI 视图层,完成 render
- 接下来来到 commit 阶段,替换真实 DOM,完成此次更新流程,最后会执行 setState 中 callback 函数,到此为止完成了一次 setState 全过程
一个主要任务的先后顺序:render 阶段 render 函数执行 -> commit 阶段真实 DOM 替换 -> setState 回调函数执行 callback
1.2 类组件 setState 原理揭秘:
类组件初始化过程中绑定了负责更新的
Updater
对象,调用 setState,实际上是 React 底层调用 Updater 对象上的enqueueSetState
方法// react-reconciler/src/ReactFiberClassComponent.js enqueueSetState(){ /* 每一次调用`setState`,react 都会创建一个 update 里面保存了 */ const update = createUpdate(expirationTime, suspenseConfig); /* callback 可以理解为 setState 回调函数,第二个参数 */ callback && (update.callback = callback) /* enqueueUpdate 把当前的update 传入当前fiber,待更新队列中 */ enqueueUpdate(fiber, update); /* 开始调度更新 */ scheduleUpdateOnFiber(fiber, expirationTime); }
enqueueSetState
会创建一个 update,然后放入当前 fiber 对象的待更新队列中,最后开启调度更新,进入到(批量)更新流程React 批量更新:
// react-dom/src/events/DOMLegacyEventPluginSystem.js /* 在`legacy`模式下,所有的事件都将经过此函数同一处理 */ function dispatchEventForLegacyPluginEventSystem(){ // handleTopLevel 事件处理函数 batchedEventUpdates(handleTopLevel, bookKeeping); }// react-dom/src/events/ReactDOMUpdateBatching.js function batchedEventUpdates(fn,a){ /* 开启批量更新 */ isBatchingEventUpdates = true; try { /* 这里执行了的事件处理函数, 比如在一次点击事件中触发setState,那么它将在这个函数内执行 */ return batchedEventUpdatesImpl(fn, a, b); } finally { /* try 里面 return 不会影响 finally 执行 */ /* 完成一次事件,批量更新 */ isBatchingEventUpdates = false; } }
- 在 React 事件执行之前通过
isBatchingEventUpdates = true
打开开关,开启事件批量更新,当该事件结束,再通过isBatchingEventUpdates = false
关闭开关,然后在·scheduleUpdateOnFiber `中根据这个开关来确定是否进行批量更新export default class index extends React.Component{ state = { number:0 } handleClick= () => { this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback1', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback2', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback3', this.state.number) }) console.log(this.state.number) } render(){ return <div> { this.state.number } <button onClick={ this.handleClick } >number++</button> </div> } }0, 0, 0, callback1 1 ,callback2 1 ,callback3 1
异步操作(promise 或者 setTimeout)打破批量更新规则:
setTimeout 中的 setState 为什么会多次 render?
- 因为异步出了事件系统的执行上下文:触发时 isBatchingUpdates 为 false,所以多次 setState 没有被合并处理,能够直接进行更新
setTimeout(()=>{ this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback1', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback2', this.state.number) }) console.log(this.state.number) this.setState({ number:this.state.number + 1 },()=>{ console.log( 'callback3', this.state.number) }) console.log(this.state.number) })callback1 1 , 1, callback2 2 , 2,callback3 3 , 3
异步环境继续开启批量更新模式:
React-Dom 中提供了批量更新方法unstable_batchedUpdates
,可以去手动批量更新import ReactDOM from 'react-dom' const { unstable_batchedUpdates } = ReactDOM setTimeout(()=>{ unstable_batchedUpdates(()=>{ this.setState({ number:this.state.number + 1 }) console.log(this.state.number) this.setState({ number:this.state.number + 1}) console.log(this.state.number) this.setState({ number:this.state.number + 1 }) console.log(this.state.number) }) })0 , 0 , 0 , callback1 1 , callback2 1 ,callback3 1
在实际工作中,
unstable_batchedUpdates
可以用于 Ajax 数据交互之后,合并多次 setState,或者时多次 useState —— 如果批量更新处理,一次数据交互多次改变 state 会促使视图多次渲染提升更新优先级:
React-dom 提供了 flushSync ,flushSync 可以将回调函数中的更新任务,放在一个较高的优先级中handerClick=()=>{ setTimeout(()=>{ this.setState({ number: 1 }) }) this.setState({ number: 2 }) ReactDOM.flushSync(()=>{ this.setState({ number: 3 }) }) this.setState({ number: 4 }) } render(){ console.log(this.state.number) return ... }3 4 1
首先
flushSync
this.setState({ number: 3 })
设定了一个高优先级的更新,然后 2 和 3 被批量更新到 3,最后更新 setTimeout 中的 1flushSync 中的 setState > 正常执行上下文中的 setState > setTimeout、Promise 中的 setState
1.3 函数组件 useState 原理揭秘
(未完待下一道面试题)18. 原理篇-hooks原理
2. V18
concurrent
模式下的 setState(未完待下一道面试题)34. v18特性篇-concurrent 下的 state更新流程
原文:"首先 flushSync this.setState({ number: 3 })设定了一个高优先级的更新,然后 2 和 3 被批量更新到 3,最后更新 setTimeout 中的 1"
2,3批量更新到3是不是打错了? 是2,4批量更新到4
from daily-interview-question.
Related Issues (20)
- ``` javascript HOT 2
- 反转数字字符串 HOT 2
- es11
- 实现
- [...new Set(arr.toString().split(',').sort((a,b) => a-b ))].map(item => Number(item))
- let nums1 = [3,3,2] let nums2 = [1,2,3,3,2,2,4444] function res (nums1,nums2){ let a = [] for (const item of nums1) { for (const i in nums2) { if(item==nums2[i]){ a.push(nums2[i]) nums2.splice(i,1) break } } }; return a } console.log(res(nums1,nums2))
- splice插入
- 自己回答一波,若有错误请各位指出,互相学习!谢谢 ~
- 递归
- 第226题:TS 中逆变和协变如何理解
- objmap
- 通过协程来实现
- 这代码写的...
- 第 161 题:用最精炼的代码实现数组非零非负最小值 index HOT 2
- No description provided.
- > 就我的使用来说(Vue)key的作用是为了在数据变化时强制更新组件,以避免“原地复用”带来的副作用,官方文档也说明了**不带key性能更好**,见:[List Rendering - key](https://cn.vuejs.org/v2/guide/list.html#key)
- 解释原因
- an
- 同步/异步 > 微任务>宏任务
- Object.prototype,map
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from daily-interview-question.