新技能GET!在前端表格中花式使用非同步函數的奧義

背景

60年代時,作業系統中獨立運行的單元通常是進程。但隨著電腦技術的發展,人們發現在進程運行過程中,創建、撤銷與切換都要花費較大的時空開銷。

到了80年代為了解決這一問題,出現了更小的獨立運行基本單位——執行緒。

作業系統把 CPU 處理時間劃分成許多更小的時間片,在每一個獨立時間片執行一個執行緒的指令,到下一個時間片繼續執行下一執行緒的指令,各執行緒輪流執行,由於每一個時間片時間都比較短,所有執行緒都會運行,對於使用者而言就好像所有執行緒在同時進行。最終達到的效果就是在編程時可以創建多個執行緒,同一時間運行,各執行緒可以"並行"運行,以完成不同的任務。

這時新的問題也出現了,在單獨執行緒的運行模式之下,一段程式碼調用另一段程式碼時,只能採用同步調用,只有當前程式碼執行完成返回結果之後,調用才能繼續往下執行。用一個例子就是現在只有一個水槽,一匹馬想喝水只能等上一匹馬走了才能繼續喝。

而有了多執行緒的支援,可以採用非同步函數的調用,這個問題就迎刃而解了。

非同步函數原理介紹

程式中會有很多內容,計算內容複雜、渲染內容繁多,在處理過程中需要花費比較多的時間。當某個模組A調用了模組B的處理內容時,這時模組B中的內容就需要一些時間處理,此時模組A如果不停地等待,就會嚴重影響程式性能。在實際情況中,就比如在前端頁面中需要進行在線填報的數據處理,需要對數據內容進行計算後放入表格中展示,這是由於計算並未完成,頁面內容也不顯示,給用戶帶來的感覺就是內容都點擊運行了,但是頁面遲遲沒有任何回饋。

出現了非同步函數的調用之後,此時執行的模組A和模組B分別屬於不同的執行緒。

在非同步調用中,模組A不需要等到模組B返回內容,就可以繼續執行後續程式碼。

模組B中的內容執行完畢後,會通知模組A:我這邊處理完畢,你記得處理後續內容。

藉助非同步調用,可以把剛剛我們提到的前端頁面中顯示問題進行優化:把整個初始化處理放進一個單獨執行緒,主執行緒啟動此執行緒後接著往下走,讓主窗口瞬間顯示出來。等思索需要進行的操作的內容時,數據計算處理就已經在暗中處理完畢;程式開始穩定運行以後,非同步調用還可以進一步優化人機交互的過程。用戶點擊滑鼠時進行操作的時候,操作內容比較費時,點擊後系統沒有立馬作出回應,這會讓用戶的使用體驗很糟糕。將更費時、速度更慢的操作內容轉為非同步調用,讓主執行緒隨時恭候下一條消息,這樣用戶的滑鼠操作動作響應速度更快,使用體驗自然大大提升。

實踐:專家用戶的花式使用

實例演示

我們用一個簡單的例子,看看在前端電子表格單元格計算中,如何使用非同步函數。

var ServerDecode = function () {};
ServerDecode.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction("DECODE", 1, 255);
ServerDecode.prototype.evaluateAsync = function (context, arg1) {
    $.get("decode/" + arg1, function (data, status) {
        context.setAsyncResult(data);
    });
};

spread.addCustomFunction(new ServerDecode());

sheet.setFormula(0, 1, '=DECODE(A1)');



在這個演算法中我們將設定的計算解析方法部分放在伺服器上,方法名稱叫DECODE

下一步將參數用jquery.get請求發送到伺服器中,然後獲取請求內容後完成設置

然後將整個非同步函數註冊進入Spread中

最後在B1單元格中,輸入DECODE(A1)

這樣當A1單元格內容發生變化的時候,B1就會根據我們設定的計算規則重算成對應內容

非同步函數的花式使用

工具總在不同人手中被挖掘出各種各樣的用法,而在去年冬天我們就收到了用戶回饋的非同步函數的各種奇妙使用方式。

他們使用非同步函數的參數組合成了一個SQL,發送給資料庫進行數據查詢,並在查詢結束後顯示查詢結果。結果一切正確,但是卻出現了一個小問題。

在使用過程中,用戶發現查詢在整個過程中超過了 四次 ,詢問我們是否是公式出錯?

我們當即開展問題排查,在查看源程式碼的過程中我們發現,在最早實現這個功能的時候為了強調數據重要性,當同一個公式中出現多個非同步函數調用時,再次計算下一個內容時我們還會再計算一次已經計算過的非同步函數的內容。

沒想到用戶確實會這樣使用非同步函數,這一部分內容隨後也進行整體調整。現已調整為每次調用只計算一次非同步函數。

有了這次經歷,再遇到用戶對非同步函數的其他花里胡哨的用法,我們就見怪不怪了。

果不其然,沒多久又收到了其他用戶的花式使用回饋。

這一次用戶使用非同步函數從伺服器獲取當前服務名,並在SpreadJS顯示出來。

我們發現這個用戶還在其中添加了格式字元串,用以獲取用戶的二維碼。同時在這裡還設置了條件格式,如果用戶沒有登錄會有報錯提示。

這個例子內容雖短,但在這裡用戶將非同步函數、條件、格式還有格式字元串三個功能都結合在一起使用。

總結

以上就是我們全部對非同步函數誕生背景和原理,以及在前端電子表格中非同步函數的使用和各種神仙用戶的花式使用,到本節關於電子表格計算原理的全部內容就已經介紹完畢。

覺得內容不錯點個贊再走吧~