為什麼技術支援建議加上 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

問題根源:執行順序分析

要理解為何會發生這個問題,需要了解背後的四個執行步驟:

  1. filenameToURI 方法建立了一個符號連結(symbolic link),讓應用伺服器可以存取該檔案。
  2. 指令傳送給前端,要求以非同步方式開啟該 URL。
  3. END MAIN 觸發程式結束流程,清除符號連結。
  4. 瀏覽器嘗試開啟 URL,但此時檔案已無法存取。

加入 SLEEP 1 之後,步驟 3 的清除動作被延後,讓瀏覽器有足夠的時間在符號連結被移除之前開啟檔案。然而,這只是一種臨時的補救措施,依賴固定的時間延遲並不可靠。

更好的解法

比起依賴 SLEEP 1,更根本的解法是將獨立執行的程式改寫為程式庫函式(library function)。當程式以函式形式被呼叫方程式調用時,呼叫方程式在函式執行完畢後仍然處於執行狀態,因此不會觸發提早的資源清除動作,也就自然避免了上述的競態問題。

原文:https://4js.com/ask-reuben/ig-232/  ·  有任何 Genero 技術問題或翻譯疑問,歡迎來信 support@t100.app