Concurrent
但是...在我们开始添加更多的代码之前,我们需要重构。
这种递归调用的方式有一个问题。
一旦开始进行渲染,则中途不会被停止,直至渲染完整个元素树。如果元素树很大,它可能会阻塞主线程太长时间。而如果浏览器需要做一些高优先级的事情,比如处理用户输入或保持动画的流畅性,它将不得不等待,直到渲染结束。
因此,我们可以把整个工作分割成多个小单元,在完成每个小单元工作时,若浏览器有更高优先级的事务处理,则可以中断 react 元素的渲染。
我们使用 requestIdleCallback
来实现一个工作轮询。你可以把 requestIdleCallback
视为 setTimeout
,但不是我们告诉它何时运行,而是浏览器在主线程空闲时运行回调。
note
react 新版本已经不再使用 requestIdleCallback
了。而是改为使用调度器实现,此用例仅做简单实现,因此依然使用 requestIdleCallback
实现。 requestIdleCallback
会提供一个 deadline
参数,可以用它来检查在浏览器需要再次控制之前我们还有多少时间。
要开始使用这个轮询,我们需要设置第一个工作单元,然后写一个 performUnitOfWork
函数,它不仅执行工作单元,还返回下一个工作单元。