2017-03-02 51 views
0

即使問這個問題我也很難,因爲我不明白髮生了什麼。Javascript方法的工作原理並不起作用

基本上,我有一個旋轉加載程序元素,應該在我的JavaScript運行時顯示。在JavaScript的結尾,加載程序應該被關閉,並且應該顯示一個模式,並從數據庫中查詢數據。問題是加載程序從不顯示。當查詢在創建模式之前運行時,約等待1-2秒。

function includeConnectionJS() { 
    if (!(typeof sforce === "object")) { 
     var connectionJS = document.createElement('script'); 
     var documentHead = document.getElementsByTagName('head')[0]; 

     connectionJS.src = '/soap/ajax/38.0/connection.js'; 
     connectionJS.setAttribute('onload', 'createLoader();createModal();'); 
     documentHead.appendChild(connectionJS); 
    } else { 
     createLoader(); 
     // Checks to see if the loader element exists. If it does not, create the element and than toggle it to display it. 
     // If the element already exists, display the modal 
     createModal(); 
     // Checks to see if the modal element exists, if it does not, create the element and than turn off the loader and display the modal. 
     // If the element already exists, turn off the loader and display the modal 
    } 
} 

我把console.logs在我的方法,我可以清楚地看到,該方法被調用時,如果語句都傳遞和元素的可見性在正確的時間正在發生變化,以正確的值。一切似乎暗示它應該工作,但元素從未實際顯示。

我能夠得到它通過改變調用createModal顯示看起來像下面這樣:

setTimeout(function(){createModal()}, 100); // Most values for delay worked. 

我不想只是創造一個人爲延遲,以顯示效果裝載機。

我主要關心的是createModal方法調用數據庫。這些會導致JavaScript執行延遲(我將它們同步調用,而不是異步調用)。在查詢之前,我可以清楚地看到加載程序顯示設置爲'block',查看所有查詢調用並返回,並以正確的順序將加載程序顯示更改回'none'。更重要的是,如果我調用createLoader();方法直接從控制檯,它的工作原理。

我只是無法弄清楚我失蹤的是什麼。

+0

你所描述的一切,從正確的命令到'setTimeout'「修復」這個問題,聽起來像'createModal()',過早地關閉了加載器。如果沒有看到其他代碼,我們無法幫助您。在黑暗中拍攝:如果你想在B發生後告訴JS做A(),你需要傳遞'function(){A(); }',而不是'A();'。 –

+0

@ChrisG不,它的本質是阻止更新到用戶界面,直到正在執行的代碼完全完成。另外JavaScript在單線程中按順序執行,所以'A'總是在'B'之後執行以用於'B(); A();'。 'A'永遠不能啓動,直到'B'完成 –

回答

1

通過同步Javascript調用,您將阻止在Event Loop https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoop#Run-to-completion中排隊的用戶界面和其他功能。記住Javascript代碼在單線程中執行很重要。所以沒有代碼可以並行執行,其他任何事情都必須等到當前任務完成。在實踐中,這意味着你希望你的函數儘快完成他們的工作,以便其他操作(UI更新,鍵盤/鼠標事件等,超時或異步回調等)可以執行。他們都必須等到你通過完成當前的代碼塊來控制引擎。

setTimeout的作品,因爲它增加了在未來某個時候長時間運行的createModal功能事件隊列執行(即使設置爲0毫秒 - 它並不能保證立即執行它只是說,在第一次機會就可以了0毫秒後的某個時間如果你有一個長時間運行的函數,實際上可能在10秒以後)。這樣做可以使調用函數快速完成,UI現在可以應用任何更新。現在,當JavaScript引擎準備好運行更多代碼時,它將查找事件循環中記錄的下一代碼塊。這次它運行的時候它會再次阻止對UI等的更新,處理鼠標鍵盤事件等等,但是現在UI已經有機會更新了,你會讓你的微調起來。

所以選擇是:或者在你的函數中使用異步調用,以便它快速完成,或者如果這是不可能的,繼續使用setTimeout()在UI更新後對長時間運行的任務進行排隊。