為什麼技術支援建議加上 SLEEP 1?
技術支援團隊在排查問題時,偶爾會建議在程式碼中加入 SLEEP 1。有些開發者在問題解決後,便將這行程式碼永久保留下來。這個建議的背後,其實與 Genero 的主從式架構(client-server architecture)密切相關——後端的 fglrun 程序與前端(gbc.js / gdc.exe)是獨立運作的兩個元件。
典型問題範例
以下是一個常見的檔案顯示失敗情境:
LET uri = ui.Interface.filenameToURI("myimage.png")
CALL ui.Interface.frontCall("standard", "launchURL", [uri], [])
END MAIN
這段程式碼執行後,圖片無法正常顯示,原因是「前端呼叫(front call)觸發時,找不到對應的檔案」。
加上 SLEEP 的解法
技術支援建議的暫時解法,是在前端呼叫之後插入一段延遲:
LET uri = ui.Interface.filenameToURI("myimage.png")
CALL ui.Interface.frontCall("standard", "launchURL", [uri], [])
SLEEP 1
END MAIN
問題根源:執行順序分析
要理解為何會發生這個問題,需要了解背後的四個執行步驟:
filenameToURI方法建立了一個符號連結(symbolic link),讓應用伺服器可以存取該檔案。- 指令傳送給前端,要求以非同步方式開啟該 URL。
END MAIN觸發程式結束流程,清除符號連結。- 瀏覽器嘗試開啟 URL,但此時檔案已無法存取。
加入 SLEEP 1 之後,步驟 3 的清除動作被延後,讓瀏覽器有足夠的時間在符號連結被移除之前開啟檔案。然而,這只是一種臨時的補救措施,依賴固定的時間延遲並不可靠。
更好的解法
比起依賴 SLEEP 1,更根本的解法是將獨立執行的程式改寫為程式庫函式(library function)。當程式以函式形式被呼叫方程式調用時,呼叫方程式在函式執行完畢後仍然處於執行狀態,因此不會觸發提早的資源清除動作,也就自然避免了上述的競態問題。
原文:https://4js.com/ask-reuben/ig-232/
· 有任何 Genero 技術問題或翻譯疑問,歡迎來信
support@t100.app