[英]Code responding in JavaScript for huge calculations
摘自《 Understanding ECMASCript 6》一書中的引用:
JavaScript引擎建立在單線程事件循環的概念上。 單線程意味着一次只執行一段代碼。
...
JavaScript引擎一次只能執行一段代碼,因此它們需要跟蹤要運行的代碼。 該代碼保存在作業隊列中。 每當准備好執行一段代碼時,就會將其添加到作業隊列中。 當JavaScript引擎執行完代碼后,事件循環將執行隊列中的下一個作業。 事件循環是JavaScript引擎內部的一個過程,用於監視代碼執行並管理作業隊列。 請記住,作為隊列,作業執行從隊列中的第一個作業運行到最后一個作業。
這是否意味着如果作業隊列中的下一段代碼花費大量時間,則Web應用程序將不會響應,直到代碼完成為止? “代碼段”的大小是多少? 它是函數體還是代碼塊(即{}括號內的代碼)? 函數主體包含其他函數調用(這是兔子洞...)。 這讓我感到困惑。
例如,它可能是用於Promise實例初始化的函數的巨大代碼,也可以是.then((resolve,reject)=> {...}
中的巨大代碼:
// ...
const p = new Promise((resolve, reject) => {
// Here is long work
// ...
});
// ...
p.then(() => {
// Or long work is here
// ...
});
這是否意味着如果作業隊列中的下一段代碼花費大量時間,則Web應用程序將不會響應,直到代碼完成為止?
基本上是的,在事件循環中運行代碼時, 時間復雜度非常重要。 例如,在nodejs中,不建議使用加密api的同步版本,即:
crypto.randomBytes (synchronous version)
crypto.randomFillSync
crypto.pbkdf2Sync
因為它們涉及昂貴的計算。
“代碼段”的大小是多少? 它是函數體還是代碼塊(即{}括號內的代碼)?
從您的引用中,“代碼段”我認為它只是指一條語句,因此單個線程一次只能執行一個語句,因此不會發生並行執行,而只能通過多個線程來實現。
旁注:比“代碼的大小”更重要的是計算復雜性 。 相當大的“一段代碼大小”可以在恆定時間O(1)上運行,而較小的代碼段則需要花費指數時間。
更多信息在這里 ,特別是對谷歌的V8發動機。
TL; DR :計算復雜性很重要,尤其是在單線程引擎中。 對於長時間運行的計算,請在瀏覽器中使用Web Worker,或者在使用Node的情況下使用子進程。
您可以為每個函數設置setInterval以減少執行腳本的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.