在我的应用程序中,在某一时刻,我通过承诺将如此多的微任务排队,导致UI被阻塞并变得没有响应。
有任何方法可以以类似的方式将它们作为宏任务排队吗?使用setTimeout()可以很好地工作,UI再次响应,但是代码非常丑陋,让我陷入了回调的泥潭。
提前感谢!
发布于 2019-12-06 05:15:30
如果您排队等待足够多的承诺来饿死UI,因为承诺比许多其他类型的事件具有更高的优先级,那么您可能只是一次运行太多的异步操作,或者编写代码的方式产生了太多的承诺,而这些承诺必须被调度并与其他事情竞争。
修复这个问题的正确方法可能是修复您的代码,因此它不会试图创建那么多的承诺。只有当你向我们展示导致这个问题的代码时,我们才能帮助你。
有任何方法可以以类似的方式将它们作为宏任务排队吗?
在JS中内置的承诺实现不能使其可配置如何调度承诺,因此它们被硬连接起来使用比事件队列中的许多其他事情优先级更高的微任务,而且您无法改变这一点。
您可以获得一个第三方库(在JS有内置的承诺之前,它是为承诺使用而构建的),它没有访问微任务系统的权限,并且可能使用类似于setTimeout()或setImmediate()之类的东西。但是,您必须确保所有代码都切换到这个第三方库,而不是无意中使用内置实现。
老实说,这感觉像是一次彻底的黑客攻击,不是我想要的解决方案。单线程JS是一个协作系统。为了保持UI响应性,它依赖于一些协作,而不是锤击具有高优先级或长时间运行操作的主线程,以保持UI响应。
在某些情况下,您可以将一些代码移至webWorker (如果这是浏览器)或WorkerThread (如果这是node.js ),并将麻烦的代码从与UI相同的事件循环中提取出来。
但是,最好的解决方案可能是驯服您的承诺驱动代码,这样它就不会连续运行那么多承诺计划的事情,从而干扰UI。如果您向我们展示了导致问题的承诺代码,那么我们只能提供一些关于如何做到这一点的想法。
发布于 2019-12-06 05:25:13
一旦你创造了一个承诺,承诺就会实现。因此,承诺创造需要排队。执行这类操作的最佳包之一称为异步。在写这篇文章的时候,它在吉突布有26.2K的恒星。
查看他们的文档中的队列示例,以便更好地了解它的工作方式:
// create a queue object with concurrency 2
var q = async.queue(function(task, callback) {
console.log('hello ' + task.name);
callback();
}, 2);
// assign a callback
q.drain(function() {
console.log('all items have been processed');
});
// or await the end
await q.drain()
// assign an error callback
q.error(function(err, task) {
console.error('task experienced an error');
});
// add some items to the queue
q.push({name: 'foo'}, function(err) {
console.log('finished processing foo');
});
// callback is optional
q.push({name: 'bar'});
// add some items to the queue (batch-wise)
q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
console.log('finished processing item');
});
// add some items to the front of the queue
q.unshift({name: 'bar'}, function (err) {
console.log('finished processing bar');
});https://stackoverflow.com/questions/59207082
复制相似问题