首页 > 解决方案 > Javascript 异步承诺作为宏任务

问题描述

在我的应用程序中,有时我通过承诺 UI 被阻塞并变得无响应来排队这么多微任务。

有什么方法可以以类似的方式将它们作为宏任务排队?使用 setTimeout() 工作正常,UI 再次变得响应,但代码非常丑陋,让我陷入回调地狱。

提前致谢!

标签: javascriptconcurrencypromiseasync-await

解决方案


如果由于 promise 的运行优先级高于许多其他类型的事件,您排队的 promise 数量足以使 UI 饿死,那么您可能只是试图一次运行太多异步操作,或者编写代码的方式太远了许多承诺必须被安排并与其他事物竞争。

解决这个问题的正确方法可能是修复你的代码,这样它就不会试图创建那么多的 Promise。如果您向我们展示实际导致该问题的代码,我们只能为您提供帮助。

有什么方法可以以类似的方式将它们作为宏任务排队?

内置于 JS 中的 Promise 实现无法配置如何安排 Promise,因此它们被硬连线以使用比事件队列中的许多其他事物具有更高优先级的微任务,并且您无法更改它。

你可以得到一个第三方库(在 JS 内置 Promise 之前为 Promise 使用而构建的库),它无法访问微任务系统并且会使用类似setTimeout()or的东西setImmediate()。但是,您必须以某种方式确保您的所有代码都切换到这个第 3 方库,而不是无意中使用了内置实现。

老实说,这感觉就像一个彻头彻尾的黑客攻击,而不是我会追求的解决方案。单线程 JS 是一个协作系统。为了保持 UI 响应,它依赖于一些合作,而不是用高优先级或长时间运行的操作锤击主线程以保持 UI 响应。

在某些情况下,您可以将一些代码移出到 webWorker(如果这是浏览器)或 WorkerThread(如果这是 node.js),并将麻烦的代码移出与 UI 相同的事件循环。

但是,最好的解决方案可能是驯服你的 Promise 驱动的代码,这样它就不会连续运行这么多 Promise 计划的东西,以免干扰 UI。如果您向我们展示实际导致问题的承诺代码,我们只能提供一些关于如何做到这一点的想法。


推荐阅读