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

葡萄城技術團隊發表於2021-11-17

背景

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顯示出來。

我們發現這個使用者還在其中新增了格式字串,用以獲取使用者的二維碼。同時在這裡還設定了條件格式,如果使用者沒有登入會有報錯提示。

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

總結

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

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

相關文章