Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 什么';是';等待0';? 总结_Javascript_Lit Html - Fatal编程技术网

Javascript 什么';是';等待0';? 总结

Javascript 什么';是';等待0';? 总结,javascript,lit-html,Javascript,Lit Html,我正在查看,invalidate()函数中有一个奇怪的代码:'await 0'。我想知道这个代码的目的是什么 背景 我在谷歌上搜索了一下,但找不到这样的案例。我对javascript和Webpack非常陌生,所以我不知道如何调试应用程序(我尝试将其与--devtool选项重新绑定,但出现了错误) 作者的解释是(抱歉翻译): litRender.js可以在src/libs下找到,并帮助呈现此应用程序的每个组件。每个组件都混合使用litRender,形式为类SomeComponent扩展litRen

我正在查看,
invalidate()函数中有一个奇怪的代码:'await 0'。我想知道这个代码的目的是什么

背景 我在谷歌上搜索了一下,但找不到这样的案例。我对javascript和Webpack非常陌生,所以我不知道如何调试应用程序(我尝试将其与--devtool选项重新绑定,但出现了错误)

作者的解释是(抱歉翻译):

litRender.js
可以在
src/libs
下找到,并帮助呈现此应用程序的每个组件。每个组件都混合使用
litRender
,形式为
类SomeComponent扩展litRender(HTMLElement)
。如果内容多次更新,则时间代码旨在通过不每次渲染来帮助提高性能,它会收集渲染时间。对扩展它的组件调用this.invalidate将保留对该组件中定义的呈现函数的调用

正如作者前面提到的,
invalidate()
用于渲染阴影DOM

主要问题
我想知道
litRender.js
中的'await 0'到底是什么意思。

await
必须在
async
代码中使用statement,以便文档在说明部分中说,
await
将用于暂停函数的执行,直到承诺得到解决或拒绝,因此,如果在<>代码>下等待“< /代码>”不是一个允诺,那么JS会考虑作为一个解决的承诺。
希望它能帮助您理解。

一年后,我终于找到了答案:
等待0
用于释放事件循环,以便浏览器可以绘制框架

注意:我的解释很冗长,语法用法也不好。阅读上面链接的MDN文档可能更好。

由于JS被设计为单线程(同时存在一个web worker)语言,因此它有一个称为事件循环的并发模型。考虑以下情况:

console.log('before timeout')
setTimeout(()=>console.log('insidetimeout'),0)
console.log('超时后')
结果将是:

before timeout
after timeout
inside timeout
一开始可能会让人困惑。您可能认为:超时设置为延迟0,因此它将在执行下一行代码之前执行回调!但事实并非如此

为了理解上面的代码,让我们首先看看JS如何处理代码执行。它有一个名为stack的存储器,用于跟踪当前函数执行的起始位置

函数a(){
console.log('a()'))
}
()
console.log('end')
在上面的代码中,首先执行括号外的代码。然后,将执行函数a。此时,堆栈将如下所示:

    a
(Main) -> code outside every brackets
如果某个函数调用另一个函数,则被调用的函数将叠加在前一个函数上。现在,函数end和JS从堆栈顶部清除它,返回到上一个位置,执行剩余的代码,直到到达末尾,依此类推。通过利用堆栈,JS可以确定在当前函数结束后要去哪里

那么当我们执行setTimeout时会发生什么呢?这里重要的一点是,setTimeout不是一种语言功能,而是浏览器处理的一种平台功能。浏览器等待给定的时间,同时继续执行以下代码。然后超时结束,浏览器需要执行其回调,但问题是另一段代码可能仍在执行中。为了解决这个问题,浏览器将回调作为任务,并将其注册到任务队列中。当堆栈为空时,其中的任务将按顺序执行

这解释了第一个代码段的奇怪行为:setTimeout的回调被注册为task,并等待堆栈为空。记录第二条消息后,主代码执行结束,回调函数最终执行


承诺的处理方式与此类似(但不尽相同)。无论wait的右侧是否是一个承诺,在wait之后需要执行的每个代码都会注册为微任务。这样做的主要好处是,当堆栈为空时,浏览器仅绘制帧。通过将剩余代码注册为微任务堆栈在微任务执行之前变为空,所以浏览器可以在该时间内绘制帧

如果我没有错的话,这会增加延迟,所以我确信这与性能有关<代码>等待0
将强制上述代码等待承诺解析,以便执行下一个代码。Promises实现本身会引入延迟,因此这将略微降低该函数调用的执行量,特别是提高整体性能。正如您所看到的,实际上,如果(!instant),则在
中调用该函数,否则等待将被忽略。类似于将函数执行包装到超时为
0
setTimeout
函数中,或包装到
Promise.resolve().then()
方法中。作为旁注,这可能有助于您理解(或可能使您更加困惑),您可以尝试键入脚本并查看异步函数的编译代码:。这并不容易理解,但您可能会注意到,如果返回
wait 0
,执行将花费更多时间(请查看页面右侧文本区域的b()编译函数)@briosheje感谢您的帮助。据我所知,
invalidate()
将阻止同时渲染阴影DOM。它将尝试不同时完成工作(如果可能的话)。我错了吗?@kimjs3550我想这只会延迟渲染函数的执行。我不确定这是否会阻止同时渲染阴影DOM元素,但它肯定会减少调用堆栈。我会把这个问题留给更专业的人,我真的不能预见