我看到 Jason Teplitz 撰写的一些examples关于在Angular 2中使用网络工作者的文章。 Angular 4 CLI 现在支持{{3}在工作线程中运行应用程序。 platform-worker就是一个很好的例子。或者这个一步一步factorial example。
使用 platform-worker 保证所有长计算操作都在Web worker中运行?或者我应该创建另一个角度模块(不是应用程序模块),它使用platform-worker来运行长计算操作?因此,将有两个模块,一个用于应用程序,另一个用于长时间操作?
我应该在此example中创建单独的Worker
来创建工作线程吗?
如何根据操作进度更新UI?我假设如果长操作是在for循环中完成的,那么在循环完成之前,它不会让UI知道进度吗?我应该将长操作分成多个小操作并更新UI吗?
答案 0 :(得分:2)
我会尝试提供至少一个占位符答案,直到我们能够得到更详尽的答案:
使用 platform-worker 可确保您的代码在Web worker中运行。 Angular仍然必须在"这一方面运行一些代码"在UI线程上,但是 platform-worker 基本上将所有代码和逻辑移动到工作线程中,计算所有DOM调用,当时机成熟时,它会用它调用你的DOM&# 39; s魔术。但这不是全局,所以让我们考虑一下事情。
你的问题意味着一些繁重的计算工作。没有繁重的UI工作,但繁重的计算工作。这与仅卸载主线程上的所有UI工作不同。
如果您有大量的应用程序(如具有许多绑定的大型表,或许多运行大量CPU繁重任务的组件),那么可能会被视为繁重的应用程序。将它卸载给工人绝对是值得的。但是,如果您的应用程序不是那么复杂,而且只有某些工作,那么您可以考虑将应用程序与您的工作分开。即使您将应用程序卸载给工作人员,如果有一项任务会导致整个工作人员暂停一段时间,那么整个应用程序,UI和所有应用程序都会暂时无响应。当然,您可以滚动并单击,但有角度,因为它与长时间运行的繁重同步任务位于同一个线程上,没有机会响应。所以它几乎与在UI线程上运行的一样。
这就是为什么我相信你仍然可以为你的繁重任务创建一个单独的工人。你也需要给Angular一个呼吸的地方。
您还担心如何更新for循环中的内容。好吧,如果您有一个长期运行的同步任务 - 那么您需要在该作业运行器中的循环运行之间提供更新。
为什么呢?因为,如果你不能停止运行(同步东西),那么angular将没有机会退出代码(在web worker中)并将消息发布到UI线程(和角度的UI部分)并更新UI。或者如果你有一个单独的工人工作,它只是不知道角度已经走了多远。
因此,如果您的整个应用程序都在Web工作者中(与重CPU逻辑一起),您可以,例如每100次迭代,更新一些本地可观察或类似的,并设置下一个循环运行以便稍后在setTimeout中运行。它应该让Angular有机会将这个可观察值的更新发送给DOM渲染器,DOM渲染器又可以通知UI线程更改。
如果您的应用程序位于一个单独的工作人员而不是实际占用大量CPU的任务中,那么您仍然需要将每次(例如100次迭代)的此更新发送到Angular应用程序。
通过这种方式,您的Angular应用程序仍然具有响应能力,您仍然可以拥有一个服务,该服务可以侦听此工作人员的作业进度更新并更新UI。 (再次,例如,每100个循环运行一条消息到工作者的另一端)。例如。你只是在某处显示一个微调器,当用户点击时,它会显示任务的距离,并且用户可以使用该应用的其他部分。
如果您提供有关密集型CPU任务的更多详细信息,也许有人可以提供更好的答案。我希望这个有助于至少清楚一点。