javascript同一個 function 在共用時的處理,透過callback來避免全域變數的使用

使用情境:

一開始在 workflow table 裡寫了一個 ajax 的 load_workflow() function 來載入 workflow 的 table 內容,

後來在 workflow_editor 的圖層裡, 也希望可以共用這一個 load_workflow() fucntion, 但是希望在成功載入伺服器回傳的資料後, 可以再多做其他額外的UI 的處理.

透過增加 variable 改變程式流程的寫法:

var load_wokflow_and_open_workflow_editor = false;
var global_workflow_id=0;

function load_workflow()
{
  if(load_wokflow_and_open_workflow_editor) 
  {
    if(global_workflow_id > 0) {
      open_workflow_editor_by_id(global_workflow_id);
    }
  }
  load_wokflow_and_open_workflow_editor = false;
}

這個寫法的耦合性高, 且不方便再往上長大, 功能愈多共用時, 會造成在 load_workflow() function 裡, 出現很多不是關於 workflow talbe 裡的程式碼.

解法很簡單:

  • 分成 load_workflow() 與 load_workflow_callback() 2個 function,
  • 原本的程式都搬到 load_workflow_callback(),
  • 寫一個全新的 load_workflow() function, 固定傳一個空的 callback function 到 load_workflow_callback() 裡,

把 function 當成 callback 傳入寫法:

function load_workflow()
{
    load_workflow_callback(() =>
    {
        compose_workflow_table(data);
    }
    );
}

function load_workflow_callback(callback)
{
    fetch(api_url,{
        method: 'POST',
        body: body
    }
    ).then(function (response)
    {
        return response.json();
    }
    ).then(function (data)
    {
        callback(data);
    }
    ).catch(function (err)
    {
        console.log(err);
    }
    );
}

除了 () => {} 寫法, 也可以使用 function(){}


另一個使用情境: 要比較 workflow version1 與 version 2,

解法有2個:

  • 只呼叫一個 restful api, 在 server side 裡 read 2個 version.
  • 使用既有的一次只load 1個 version 的 api 來使用, 由於不確定載入的 ajax version 1 與 version 2 呼叫二次時, 那一個 request 會比較快回來, 所以變成要在第一個 resetful api 的完成的 block 裡, 再去呼叫第二次, 以這個情境來說, 使用的 javascript 範例如下:
reset_workflow_editor_config();
load_workflow_component_by_workflow_version_callback(workflow_id, previous_version_id, function (data_1)
{
    load_workflow_component_list_to_list(data_1);
    component_version_array_before = JSON.parse(JSON.stringify(getComponentVersionArray()));
    reset_workflow_editor_config();
    load_workflow_component_by_workflow_version_callback(workflow_id, current_version_id, function (data_2)
    {
        load_workflow_component_list_to_list(data_2);
        //component_version_array_after = JSON.parse(JSON.stringify(getComponentVersionArray()));
        let is_component_arugment_changed = check_workflow_diff_compoent_argument_changed();

    }
    );
}
);

說明:

  • 上面的程式碼, 因為又用了全域變成來放資料, 所以使用前, 要先 reset 一下全域變數內容變成初始值. 要解決全域變數的話, 就要把全域變數再換成參數來傳遞.
  • 這個範例, 在 callback 裡, 再呼叫一次 resetful all, 並交待第二次 restful api 成功時要執行的 callback.

相關文章

How To Convert An SVG To An Image In The Browser?
https://stackoverflow.max-everyday.com/2023/03/how-to-convert-an-svg-to-an-image-in-the-browser/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *