Javascript Promises库在浏览器中制作“长时间运行代码 - 非阻塞UI”?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript Promises库在浏览器中制作“长时间运行代码 - 非阻塞UI”?相关的知识,希望对你有一定的参考价值。
更新
这是对下面问题的更新,应该有助于找到答案
接受torazaburo的答案,Promise/A+也引用了部分杰出的javascript Promise / A +定义,我想在此更新问题。
onFulfilled
规范在第2.2.4点建议:
在执行上下文堆栈仅包含平台代码之前,不得调用onFulfilled或onRejected。 3.1。
并进一步解释
这里的“平台代码”意味着引擎,环境和承诺实现代码。实际上,这个要求确保onFulfilled和onRejected异步执行,然后调用事件循环,然后调用新堆栈。这可以使用诸如setTimeout或setImmediate之类的“宏任务”机制,或者使用诸如MutationObserver或process.nextTick之类的“微任务”机制来实现。由于promise实现被认为是平台代码,因此它本身可能包含一个任务调度队列或“trampoline”,其中调用处理程序。
我期待在这个问题中找到的这个问题是,关键是Promise实现Javascript代码本身被认为是平台代码,并且允许不通过调用onRejected
onFulfilled
函数来解决后续promise之间的eventloop。这在Node.js(服务器)中是很好的,因为它避免了回到事件循环(离开执行堆栈)的不必要的回归,但也导致浏览器中的挑战,因为执行堆栈没有退出,在解决潜在的大承诺的数量(它们本身可以产生新的承诺)。不离开执行堆栈并屈服于事件循环会导致浏览器出现意外(阻塞脚本警告/问题)。然而,导致这种需要的Promise实现的“trampoline”任务调度不必避免不时地将执行交还给Javascript事件循环。这样的功能允许将Promise用于较重的任务。在这个问题中搜索/要求这种“长期运行代码”的Promises实现。
澄清:“过长”不是onFulfilled
函数的个体长度,而是由于Promise解析过程(当以这样的“蹦床”方式完成时)将几个函数/回调连接在一起。我已经意识到,如果一个人的Promises
函数太长,那么使用任何类型的Promise实现都无法以任何方式帮助它。
这里的交易是x promises的后续解析(在一个执行堆栈内,因此没有回到Javascript事件循环)可能会导致Javascript代码执行的持续时间过长。这在浏览器中很糟糕(因为阻塞)。
这个问题
在Javascript中,Q允许处理异步编程任务。大!
已经有一些实现和库围绕WinJS,when.js或then(onFullfilled,onReject)
仅举几例。看了之后我就看到他们在Javascript异步编程挑战中处理了一些“特殊的东西”。
通常我认为他们这样做是为了解决承诺
- 转到承诺的内部列表
- 检查是否履行了承诺+运行所有相关的(通过qazxsw poi)功能。
- (在某些情况下,我们在这里完成)
- (在其他情况下,仍有“未决”承诺)
这种情况(4)是因为让它们(其余的承诺)满了将需要当前的Javascript代码(这是承诺解析的代码)停止运行并允许JS event loop
发生(即异步事件,如XHR请求,或用户界面互动)。为了使这个(4)工作,承诺解决方案规范召回(即通过setTimeout / setImmediate)并在event loop
运行之后继续,因此可能已经解决了一些“未决”承诺(=拒绝/已满)。
我担心的是,第1步和第2步可能会运行很长一段时间,只是在执行到event loop
时才会执行,以防它似乎表示要解决一些“未决”的承诺。虽然在某些情况下(即在服务器/ Node.js上)“好”,但在浏览器中这是非常有问题的,因为即使向event loop
释放执行并且UI没有阻塞也没有问题,但这并没有完成在我所见过的承诺的实施中。
因此我的问题是:你知道一个关心方面的promise实现(Javascript Promises库): 在浏览器中制作“long-running-code-non-blocking-UI”?
这意味着承诺解决方案将自愿释放执行回event loop
,以便CSS动画,用户输入,鼠标交互,确实得到足够的关注,并且不会有“警告:无响应脚本”消息。
任何兼容的promises实现都不会同步运行then
函数,而只是在下一个tick。因此,您担心“第1步和第2步可能会运行很长一段时间”是没有根据的。
来自Promises / A +规范:
在执行上下文堆栈仅包含平台代码之前,不得调用
onFulfilled
或onRejected
。这里的“平台代码”意味着引擎,环境和承诺实现代码。在实践中,这个要求确保
onFulfilled
和onRejected
异步执行,然后调用事件循环,并使用新堆栈。
换句话说,您在2)下的配方是不正确的。 promises实现不“运行相关的函数”,它会安排它们。
如果处理程序本身是“长时间运行”的代码,这对你无能为力 - 实际上没有办法帮助你。
我认为解决方案可能是解析长时间运行的JavaScript代码,例如使用https://github.com/NeilFraser/JS-Interpreter。
它会使代码更慢,但您可以指定优先级:
const myInterpreter = new Interpreter(myCode);
function nextStep() {
if (myInterpreter.step()) {
window.setTimeout(nextStep, 100/speed);
}
}
nextStep();
以上是关于Javascript Promises库在浏览器中制作“长时间运行代码 - 非阻塞UI”?的主要内容,如果未能解决你的问题,请参考以下文章
现代JS中的流程控制:详解Callbacks Promises Async/Await
现代JS中的流程控制:详解Callbacks Promises Async/Await
Mongoose 的默认 Promise 库在 MEAN 堆栈中已弃用
JavaScript 中的 Promises/Fetch:如何从文本文件中提取文本